@midscene/test 1.12.5 → 1.12.6-beta-20260909034232.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/1~891.mjs +1 -3
- package/dist/es/1~891.mjs.map +1 -1
- package/dist/es/android/index.mjs +71 -4
- package/dist/es/android/index.mjs.map +1 -1
- package/dist/es/cli/index.mjs +499 -25
- package/dist/es/cli/index.mjs.map +1 -1
- package/dist/es/harmony/index.mjs +71 -4
- package/dist/es/harmony/index.mjs.map +1 -1
- package/dist/es/index.mjs +478 -25
- package/dist/es/index.mjs.map +1 -1
- package/dist/es/ios/index.mjs +71 -4
- package/dist/es/ios/index.mjs.map +1 -1
- package/dist/es/midscene/index.mjs +71 -4
- package/dist/es/midscene/index.mjs.map +1 -1
- package/dist/es/test-cli.mjs +500 -25
- package/dist/es/test-cli.mjs.map +1 -1
- package/dist/lib/0~458.js +1 -3
- package/dist/lib/0~458.js.map +1 -1
- package/dist/lib/android/index.js +72 -4
- package/dist/lib/android/index.js.map +1 -1
- package/dist/lib/cli/index.js +499 -25
- package/dist/lib/cli/index.js.map +1 -1
- package/dist/lib/harmony/index.js +72 -4
- package/dist/lib/harmony/index.js.map +1 -1
- package/dist/lib/index.js +494 -26
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/ios/index.js +72 -4
- package/dist/lib/ios/index.js.map +1 -1
- package/dist/lib/midscene/index.js +72 -4
- package/dist/lib/midscene/index.js.map +1 -1
- package/dist/lib/test-cli.js +500 -25
- package/dist/lib/test-cli.js.map +1 -1
- package/dist/types/android/index.d.ts +13 -0
- package/dist/types/cli/index.d.ts +25 -1
- package/dist/types/harmony/index.d.ts +13 -0
- package/dist/types/index.d.ts +91 -0
- package/dist/types/ios/index.d.ts +13 -0
- package/dist/types/midscene/index.d.ts +20 -1
- package/dist/types/playwright/index.d.ts +13 -0
- package/package.json +11 -10
package/dist/lib/ios/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
var __webpack_modules__ = {
|
|
3
3
|
"./src/errors.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
4
4
|
__webpack_require__.d(__webpack_exports__, {
|
|
5
|
+
h2: ()=>NodeExecutionError,
|
|
5
6
|
ww: ()=>NodeDefinitionError
|
|
6
7
|
});
|
|
7
8
|
function _define_property(obj, key, value) {
|
|
@@ -42,12 +43,26 @@ var __webpack_modules__ = {
|
|
|
42
43
|
});
|
|
43
44
|
}
|
|
44
45
|
}
|
|
46
|
+
class NodeExecutionError extends WorkflowError {
|
|
47
|
+
constructor(node, cause){
|
|
48
|
+
const causeMessage = cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');
|
|
49
|
+
super(`Node "${node}" failed: ${causeMessage}`, {
|
|
50
|
+
code: 'NODE_EXECUTION_ERROR',
|
|
51
|
+
details: {
|
|
52
|
+
node
|
|
53
|
+
},
|
|
54
|
+
cause
|
|
55
|
+
}), _define_property(this, "node", void 0);
|
|
56
|
+
this.node = node;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
45
59
|
},
|
|
46
60
|
"./src/midscene/index.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
47
61
|
__webpack_require__.d(__webpack_exports__, {
|
|
48
62
|
createAgentTestRunnerNodes: ()=>createAgentTestRunnerNodes
|
|
49
63
|
});
|
|
50
64
|
require("@midscene/core/agent/test-runner");
|
|
65
|
+
const logger_namespaceObject = require("@midscene/shared/logger");
|
|
51
66
|
const v4_namespaceObject = require("zod/v4");
|
|
52
67
|
var errors = __webpack_require__("./src/errors.ts");
|
|
53
68
|
const validateOptionalText = (value, field, node)=>{
|
|
@@ -97,7 +112,54 @@ var __webpack_modules__ = {
|
|
|
97
112
|
'min'
|
|
98
113
|
]).default('ms').describe('Duration unit: milliseconds, seconds, or minutes.')
|
|
99
114
|
});
|
|
100
|
-
const createAgentTestRunnerNodes = (definitions, getAgent)=>
|
|
115
|
+
const createAgentTestRunnerNodes = (definitions, getAgent)=>{
|
|
116
|
+
const activeAgentCalls = new WeakMap();
|
|
117
|
+
const runAgentCall = async (node, ctx, agent, call, captureExecutions = true)=>{
|
|
118
|
+
const scopeId = 'case' === ctx.scope ? ctx.case.runId : ctx.document.documentRunId;
|
|
119
|
+
const activeCall = activeAgentCalls.get(agent);
|
|
120
|
+
if (activeCall) throw new errors.h2(node, new Error(`The same Agent instance cannot execute overlapping Midscene Test Steps. Active scope: ${activeCall.scopeId} (${activeCall.node}); requested scope: ${scopeId} (${node}).`));
|
|
121
|
+
activeAgentCalls.set(agent, {
|
|
122
|
+
scopeId,
|
|
123
|
+
node
|
|
124
|
+
});
|
|
125
|
+
let removeListener;
|
|
126
|
+
let sawExecutionWithoutId = false;
|
|
127
|
+
const stopListening = ()=>{
|
|
128
|
+
const remove = removeListener;
|
|
129
|
+
removeListener = void 0;
|
|
130
|
+
remove?.();
|
|
131
|
+
};
|
|
132
|
+
const stopListeningOnAbort = ()=>stopListening();
|
|
133
|
+
try {
|
|
134
|
+
if (captureExecutions && agent.addDumpUpdateListener) {
|
|
135
|
+
removeListener = agent.addDumpUpdateListener((_dump, execution)=>{
|
|
136
|
+
if (!execution) return;
|
|
137
|
+
if (!execution.id) {
|
|
138
|
+
sawExecutionWithoutId = true;
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
ctx.report.addTrace({
|
|
142
|
+
type: 'midscene-execution',
|
|
143
|
+
executionId: execution.id
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
if (ctx.signal.aborted) stopListening();
|
|
147
|
+
else ctx.signal.addEventListener('abort', stopListeningOnAbort, {
|
|
148
|
+
once: true
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
return await call();
|
|
152
|
+
} finally{
|
|
153
|
+
ctx.signal.removeEventListener('abort', stopListeningOnAbort);
|
|
154
|
+
try {
|
|
155
|
+
stopListening();
|
|
156
|
+
} finally{
|
|
157
|
+
activeAgentCalls.delete(agent);
|
|
158
|
+
}
|
|
159
|
+
if (sawExecutionWithoutId) warnReportTrace(`Skipped a report trace without a stable execution id for ${node} in scope ${scopeId}.`);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
return definitions.map((definition)=>define_node_defineNode({
|
|
101
163
|
name: definition.name,
|
|
102
164
|
...void 0 === definition.title ? {} : {
|
|
103
165
|
title: definition.title
|
|
@@ -111,11 +173,17 @@ var __webpack_modules__ = {
|
|
|
111
173
|
inputSchema: definition.inputSchema,
|
|
112
174
|
async execute (ctx) {
|
|
113
175
|
const agent = await getAgent(ctx);
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
176
|
+
const call = async ()=>definition.execute(agent, ctx.input, {
|
|
177
|
+
signal: ctx.signal
|
|
178
|
+
});
|
|
179
|
+
if ('object' != typeof agent || null === agent) return call();
|
|
180
|
+
return runAgentCall(definition.name, ctx, agent, call);
|
|
117
181
|
}
|
|
118
182
|
}));
|
|
183
|
+
};
|
|
184
|
+
const warnReportTrace = (0, logger_namespaceObject.getDebug)('test-runner:report-trace', {
|
|
185
|
+
console: true
|
|
186
|
+
});
|
|
119
187
|
}
|
|
120
188
|
};
|
|
121
189
|
var __webpack_module_cache__ = {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ios/index.js","sources":["../../../src/errors.ts","../../../src/node/define-node.ts","../../../src/midscene/index.ts","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/ios/index.ts"],"sourcesContent":["import type { z } from 'zod/v4';\n\nexport interface WorkflowErrorOptions {\n code?: string;\n details?: unknown;\n cause?: unknown;\n}\n\nexport class WorkflowError extends Error {\n readonly code: string;\n readonly details?: unknown;\n\n constructor(message: string, options: WorkflowErrorOptions = {}) {\n super(message, { cause: options.cause });\n this.name = new.target.name;\n this.code = options.code ?? 'WORKFLOW_ERROR';\n this.details = options.details;\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n ...(this.details === undefined ? {} : { details: this.details }),\n };\n }\n}\n\nexport class WorkflowParseError extends WorkflowError {\n constructor(message: string, details?: unknown, cause?: unknown) {\n super(message, { code: 'WORKFLOW_PARSE_ERROR', details, cause });\n }\n}\n\nexport class NodeDefinitionError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'NODE_DEFINITION_ERROR', details });\n }\n}\n\nexport class DuplicateNodeError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string) {\n super(`Node \"${node}\" is already registered.`, {\n code: 'DUPLICATE_NODE',\n details: { node },\n });\n this.node = node;\n }\n}\n\nexport class NodeNotFoundError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string) {\n super(`Node \"${node}\" is not registered.`, {\n code: 'NODE_NOT_FOUND',\n details: { node },\n });\n this.node = node;\n }\n}\n\nexport class NodeInputValidationError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'NODE_INPUT_VALIDATION_ERROR', details });\n }\n\n static fromZod(node: string, error: z.ZodError): NodeInputValidationError {\n const issues = error.issues.map((issue) => ({\n code: issue.code,\n path: issue.path.map(String).join('.'),\n message: issue.message,\n }));\n const firstIssue = issues[0];\n const path = firstIssue?.path || '<root>';\n const message = firstIssue?.message ?? 'invalid input';\n return new NodeInputValidationError(\n `Node \"${node}\" input validation failed at \"${path}\": ${message}`,\n { node, issues },\n );\n }\n}\n\nexport class StepTimeoutError extends WorkflowError {\n readonly timeoutMs: number;\n readonly node?: string;\n\n constructor(timeoutMs: number, node?: string) {\n super(\n node\n ? `Node \"${node}\" timed out after ${timeoutMs}ms.`\n : `Step timed out after ${timeoutMs}ms.`,\n {\n code: 'STEP_TIMEOUT',\n details: { timeoutMs, ...(node === undefined ? {} : { node }) },\n },\n );\n this.timeoutMs = timeoutMs;\n this.node = node;\n }\n}\n\nexport class NodeExecutionError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string, cause: unknown) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Node \"${node}\" failed: ${causeMessage}`, {\n code: 'NODE_EXECUTION_ERROR',\n details: { node },\n cause,\n });\n this.node = node;\n }\n}\n\nexport class WorkflowLifecycleError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'WORKFLOW_LIFECYCLE_ERROR', details });\n }\n}\n\nexport class ProjectSetupError extends WorkflowError {\n constructor(cause: unknown, details: { projectName: string }) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Project \"${details.projectName}\" setup failed: ${causeMessage}`, {\n code: 'PROJECT_SETUP_ERROR',\n details,\n cause,\n });\n }\n}\n\nexport class ProjectTeardownError extends WorkflowError {\n constructor(\n cause: unknown,\n details: { projectName: string; registrationIndex: number },\n ) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Project \"${details.projectName}\" teardown failed: ${causeMessage}`, {\n code: 'PROJECT_TEARDOWN_ERROR',\n details,\n cause,\n });\n }\n}\n\nexport class NodeScopeTeardownError extends WorkflowError {\n constructor(\n cause: unknown,\n details: {\n scope: 'case' | 'document';\n scopeId: string;\n node: string;\n registrationIndex: number;\n },\n ) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(\n `${details.scope === 'case' ? 'Case attempt' : 'Workflow document'} node teardown failed for \"${details.node}\": ${causeMessage}`,\n { code: 'NODE_SCOPE_TEARDOWN_ERROR', details, cause },\n );\n }\n}\n\nexport class FatalDeviceError extends WorkflowError {\n constructor(message: string, cause?: unknown) {\n super(message, { code: 'FATAL_DEVICE_ERROR', cause });\n }\n}\n\nexport const isFatalDeviceError = (error: unknown): boolean => {\n if (error instanceof FatalDeviceError) return true;\n if (error instanceof WorkflowError && error.code === 'FATAL_DEVICE_ERROR') {\n return true;\n }\n if (\n error instanceof Error &&\n /device offline|device not found|(?:adb|bdc|device) connection (?:was )?closed/i.test(\n error.message,\n )\n ) {\n return true;\n }\n return error instanceof Error && error.cause !== undefined\n ? isFatalDeviceError(error.cause)\n : false;\n};\n\nexport class CaseExecutionError extends WorkflowError {\n readonly result: import('./engine/types').CaseRunResult;\n\n constructor(result: import('./engine/types').CaseRunResult) {\n super(`Case \"${result.name}\" failed.`, {\n code: 'CASE_EXECUTION_FAILED',\n details: { caseId: result.caseId, runId: result.runId },\n });\n this.result = result;\n }\n}\n\nexport class WorkflowDocumentExecutionError extends WorkflowError {\n readonly result: import('./engine/types').WorkflowDocumentRunResult;\n\n constructor(result: import('./engine/types').WorkflowDocumentRunResult) {\n super(`Workflow document \"${result.sourcePath}\" failed.`, {\n code: 'WORKFLOW_DOCUMENT_EXECUTION_FAILED',\n details: {\n documentId: result.documentId,\n documentRunId: result.documentRunId,\n },\n });\n this.result = result;\n }\n}\n\nexport function normalizeNodeExecutionError(\n error: unknown,\n node: string,\n): WorkflowError {\n return error instanceof WorkflowError\n ? error\n : new NodeExecutionError(node, error);\n}\n","import { z } from 'zod/v4';\nimport { NodeDefinitionError } from '../errors';\nimport type {\n DefineNodeOptions,\n DefineNodeWithSchemaOptions,\n NodeDefinition,\n NodeDefinitionWithSchema,\n NodeInputSchema,\n} from './types';\n\nconst validateOptionalText = (\n value: unknown,\n field: 'title' | 'description',\n node: string,\n): void => {\n if (\n value !== undefined &&\n (typeof value !== 'string' || value.trim().length === 0)\n ) {\n throw new NodeDefinitionError(\n `Node \"${node}\" ${field} must be a non-empty string.`,\n { node, field },\n );\n }\n};\n\nconst validateInputSchema = (schema: unknown, node: string): void => {\n if (schema === undefined) return;\n if (!(schema instanceof z.ZodObject)) {\n throw new NodeDefinitionError(\n `Node \"${node}\" inputSchema must be a Zod object schema.`,\n { node, field: 'inputSchema' },\n );\n }\n if ('$' in schema.shape) {\n throw new NodeDefinitionError(\n `Node \"${node}\" inputSchema must not declare \"$\" as an input property.`,\n { node, field: 'inputSchema.$' },\n );\n }\n};\n\nconst validateDefinition = (options: {\n name: string;\n title?: unknown;\n description?: unknown;\n stringInputKey?: unknown;\n inputSchema?: unknown;\n execute: unknown;\n}): void => {\n if (!options || typeof options !== 'object') {\n throw new NodeDefinitionError('Node definition must be an object.');\n }\n\n if (typeof options.name !== 'string' || options.name.trim().length === 0) {\n throw new NodeDefinitionError('Node name must be a non-empty string.');\n }\n\n validateOptionalText(options.title, 'title', options.name);\n validateOptionalText(options.description, 'description', options.name);\n if (\n options.stringInputKey !== undefined &&\n options.stringInputKey !== false &&\n (typeof options.stringInputKey !== 'string' ||\n options.stringInputKey.trim().length === 0)\n ) {\n throw new NodeDefinitionError(\n `Node \"${options.name}\" stringInputKey must be a non-empty string or false.`,\n { node: options.name, field: 'stringInputKey' },\n );\n }\n validateInputSchema(options.inputSchema, options.name);\n\n if (\n typeof options.stringInputKey === 'string' &&\n options.inputSchema instanceof z.ZodObject &&\n !(options.stringInputKey in options.inputSchema.shape)\n ) {\n throw new NodeDefinitionError(\n `Node \"${options.name}\" stringInputKey must reference a field in inputSchema.`,\n { node: options.name, field: 'stringInputKey' },\n );\n }\n\n if (typeof options.execute !== 'function') {\n throw new NodeDefinitionError(\n `Node \"${options.name}\" must provide an execute function.`,\n { node: options.name },\n );\n }\n};\n\nexport function defineNode<\n TSchema extends NodeInputSchema,\n TData = unknown,\n TContext = unknown,\n>(\n options: DefineNodeWithSchemaOptions<TSchema, TData, TContext>,\n): NodeDefinitionWithSchema<TSchema, TData, TContext>;\n\nexport function defineNode<\n TInput = unknown,\n TData = unknown,\n TContext = unknown,\n>(\n options: DefineNodeOptions<TInput, TData, TContext>,\n): NodeDefinition<TInput, TData, TContext>;\n\nexport function defineNode(\n options: DefineNodeOptions<any, any, any>,\n): NodeDefinition<any, any, any> {\n validateDefinition(options);\n return options;\n}\n","import {\n type AgentTestRunnerNodeDefinition,\n type AgentTestRunnerNodeProvider,\n type CommonAgentTestRunnerApi,\n aiActInputSchema,\n aiActOptionsInputSchema,\n aiAssertInputSchema,\n aiAssertOptionsInputSchema,\n aiTapInputSchema,\n insightInputSchema,\n insightOptionsInputSchema,\n locateOptionsInputSchema,\n promptImageInputSchema,\n recordToReportInputSchema,\n recordToReportOptionsInputSchema,\n reportScreenshotInputSchema,\n structuredUserPromptInputSchema,\n userPromptInputSchema,\n} from '@midscene/core/agent/test-runner';\nimport { z } from 'zod/v4';\nimport type { Awaitable } from '../engine/types';\nimport { NodeDefinitionError } from '../errors';\nimport { defineNode } from '../node/define-node';\nimport type { NodeDefinition, NodeExecutionContext } from '../node/types';\n\nexport type MidsceneUIAgent = CommonAgentTestRunnerApi;\n\nexport {\n aiActInputSchema,\n aiActOptionsInputSchema,\n aiAssertInputSchema,\n aiAssertOptionsInputSchema,\n aiTapInputSchema,\n insightInputSchema,\n insightOptionsInputSchema,\n locateOptionsInputSchema,\n promptImageInputSchema,\n recordToReportInputSchema,\n recordToReportOptionsInputSchema,\n reportScreenshotInputSchema,\n structuredUserPromptInputSchema,\n userPromptInputSchema,\n};\n\nexport interface AgentProvider<TContext> {\n getAgent(\n runId: string,\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Awaitable<MidsceneUIAgent>;\n // biome-ignore lint/suspicious/noConfusingVoidType: providers without a report intentionally return void.\n releaseAgent?(runId: string): Awaitable<AgentReleaseResult | void>;\n dispose?(): Awaitable<void>;\n}\n\nexport interface AgentReleaseResult {\n /** Absolute path to the finalized report for this Agent scope. */\n reportPath?: string;\n}\n\nexport const waitInputSchema = z.strictObject({\n duration: z.number().positive().describe('How long to wait.'),\n unit: z\n .enum(['ms', 's', 'min'])\n .default('ms')\n .describe('Duration unit: milliseconds, seconds, or minutes.'),\n});\n\nexport type AiActNodeInput = z.infer<typeof aiActInputSchema>;\nexport type AiAssertNodeInput = z.infer<typeof aiAssertInputSchema>;\nexport type AiTapNodeInput = z.infer<typeof aiTapInputSchema>;\nexport type InsightNodeInput = z.infer<typeof insightInputSchema>;\nexport type RecordToReportNodeInput = z.infer<typeof recordToReportInputSchema>;\nexport type WaitNodeInput = z.infer<typeof waitInputSchema>;\n\nexport interface CreateMidsceneNodesOptions<TContext> {\n getAgent?(\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Awaitable<MidsceneUIAgent>;\n agentProvider?: AgentProvider<TContext>;\n /** Agent class that declares the Agent-backed Nodes to register. */\n agentClass: AgentTestRunnerNodeProvider;\n}\n\nconst waitFor = async (durationMs: number, signal: AbortSignal) => {\n if (signal.aborted) {\n throw signal.reason ?? new Error('Wait aborted.');\n }\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n signal.removeEventListener('abort', abort);\n resolve();\n }, durationMs);\n const abort = () => {\n clearTimeout(timeout);\n reject(signal.reason ?? new Error('Wait aborted.'));\n };\n signal.addEventListener('abort', abort, { once: true });\n });\n};\n\n/** Adapt Agent-owned descriptions to executable Midscene Test Nodes. */\nexport const createAgentTestRunnerNodes = <TContext>(\n definitions: readonly AgentTestRunnerNodeDefinition[],\n getAgent: (\n ctx: NodeExecutionContext<unknown, TContext>,\n ) => Awaitable<unknown>,\n): readonly NodeDefinition<any, any, TContext>[] =>\n definitions.map((definition) =>\n defineNode({\n name: definition.name,\n ...(definition.title === undefined ? {} : { title: definition.title }),\n ...(definition.description === undefined\n ? {}\n : { description: definition.description }),\n ...(definition.stringInputKey === undefined\n ? {}\n : { stringInputKey: definition.stringInputKey }),\n inputSchema: definition.inputSchema,\n async execute(ctx) {\n const agent = await getAgent(ctx);\n return definition.execute(agent, ctx.input, {\n signal: ctx.signal,\n });\n },\n }),\n );\n\nexport function createMidsceneNodes<TContext>(\n options: CreateMidsceneNodesOptions<TContext>,\n): readonly NodeDefinition<any, any, TContext>[] {\n if (!options || typeof options !== 'object') {\n throw new NodeDefinitionError(\n 'createMidsceneNodes() options must be an object.',\n );\n }\n if (\n typeof options.agentProvider?.getAgent !== 'function' &&\n typeof options.getAgent !== 'function'\n ) {\n throw new NodeDefinitionError(\n 'createMidsceneNodes() requires getAgent or agentProvider.getAgent.',\n );\n }\n if (\n !options.agentClass ||\n typeof options.agentClass.getTestRunnerNodeDefinitions !== 'function'\n ) {\n throw new NodeDefinitionError(\n 'createMidsceneNodes() requires agentClass.getTestRunnerNodeDefinitions().',\n );\n }\n\n const registeredAgentScopes = new Set<string>();\n const getExecutionId = (ctx: NodeExecutionContext<unknown, TContext>) =>\n ctx.scope === 'case' ? ctx.case.runId : ctx.document.documentRunId;\n const getAgent = async (\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Promise<MidsceneUIAgent> => {\n if (!options.agentProvider) return options.getAgent!(ctx);\n const runId = getExecutionId(ctx);\n if (\n options.agentProvider.releaseAgent &&\n !registeredAgentScopes.has(runId)\n ) {\n registeredAgentScopes.add(runId);\n ctx.onTeardown(async () => {\n try {\n const released = await options.agentProvider!.releaseAgent!(runId);\n return released?.reportPath\n ? { reportPaths: [released.reportPath] }\n : undefined;\n } finally {\n registeredAgentScopes.delete(runId);\n }\n });\n }\n return options.agentProvider.getAgent(runId, ctx);\n };\n\n const agentDefinitions = options.agentClass.getTestRunnerNodeDefinitions();\n\n return [\n ...createAgentTestRunnerNodes(agentDefinitions, getAgent),\n defineNode<typeof waitInputSchema, unknown, TContext>({\n name: 'wait',\n description: 'Wait for a fixed duration while honoring cancellation.',\n stringInputKey: false,\n inputSchema: waitInputSchema,\n async execute(ctx) {\n const multiplier =\n ctx.input.unit === 'min'\n ? 60_000\n : ctx.input.unit === 's'\n ? 1_000\n : 1;\n const durationMs = ctx.input.duration * multiplier;\n await waitFor(durationMs, ctx.signal);\n return { summary: `Waited ${durationMs}ms` };\n },\n }),\n ];\n}\n","__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 type { IOSAgent } from '@midscene/ios';\nimport {\n iosAgentTestRunnerNodeDefinitions,\n launchInputSchema,\n runWdaRequestInputSchema,\n terminateInputSchema,\n wdaRequestInputSchema,\n} from '@midscene/ios/test-runner';\nexport type {\n LaunchNodeInput,\n RunWdaRequestNodeInput,\n TerminateNodeInput,\n WDAHttpMethod,\n} from '@midscene/ios/test-runner';\nimport type { Awaitable } from '../engine/types';\nimport { NodeDefinitionError } from '../errors';\nimport { createAgentTestRunnerNodes } from '../midscene';\nimport type { NodeDefinition, NodeExecutionContext } from '../node/types';\n\nexport {\n launchInputSchema,\n runWdaRequestInputSchema,\n terminateInputSchema,\n wdaRequestInputSchema,\n};\n\nexport type IOSRunnerAgent = Pick<\n IOSAgent,\n 'launch' | 'terminate' | 'runWdaRequest' | 'home' | 'appSwitcher'\n>;\n\nexport interface CreateIOSNodesOptions<TContext> {\n getAgent(\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Awaitable<IOSRunnerAgent>;\n}\n\nexport function createIOSNodes<TContext>(\n options: CreateIOSNodesOptions<TContext>,\n): readonly NodeDefinition<any, any, TContext>[] {\n if (!options || typeof options !== 'object') {\n throw new NodeDefinitionError(\n 'createIOSNodes() options must be an object.',\n );\n }\n if (typeof options.getAgent !== 'function') {\n throw new NodeDefinitionError('createIOSNodes() requires getAgent().');\n }\n\n return createAgentTestRunnerNodes(\n iosAgentTestRunnerNodeDefinitions,\n options.getAgent,\n );\n}\n"],"names":["WorkflowError","Error","undefined","message","options","NodeDefinitionError","details","validateOptionalText","value","field","node","validateInputSchema","schema","z","validateDefinition","defineNode","createAgentTestRunnerNodes","definitions","getAgent","definition","ctx","agent","__webpack_require__","key","Object","obj","prop","Symbol","createIOSNodes","iosAgentTestRunnerNodeDefinitions"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ios/index.js","sources":["../../../src/errors.ts","../../../src/node/define-node.ts","../../../src/midscene/index.ts","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/ios/index.ts"],"sourcesContent":["import type { z } from 'zod/v4';\n\nexport interface WorkflowErrorOptions {\n code?: string;\n details?: unknown;\n cause?: unknown;\n}\n\nexport class WorkflowError extends Error {\n readonly code: string;\n readonly details?: unknown;\n\n constructor(message: string, options: WorkflowErrorOptions = {}) {\n super(message, { cause: options.cause });\n this.name = new.target.name;\n this.code = options.code ?? 'WORKFLOW_ERROR';\n this.details = options.details;\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n ...(this.details === undefined ? {} : { details: this.details }),\n };\n }\n}\n\nexport class WorkflowParseError extends WorkflowError {\n constructor(message: string, details?: unknown, cause?: unknown) {\n super(message, { code: 'WORKFLOW_PARSE_ERROR', details, cause });\n }\n}\n\nexport class NodeDefinitionError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'NODE_DEFINITION_ERROR', details });\n }\n}\n\nexport class DuplicateNodeError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string) {\n super(`Node \"${node}\" is already registered.`, {\n code: 'DUPLICATE_NODE',\n details: { node },\n });\n this.node = node;\n }\n}\n\nexport class NodeNotFoundError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string) {\n super(`Node \"${node}\" is not registered.`, {\n code: 'NODE_NOT_FOUND',\n details: { node },\n });\n this.node = node;\n }\n}\n\nexport class NodeInputValidationError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'NODE_INPUT_VALIDATION_ERROR', details });\n }\n\n static fromZod(node: string, error: z.ZodError): NodeInputValidationError {\n const issues = error.issues.map((issue) => ({\n code: issue.code,\n path: issue.path.map(String).join('.'),\n message: issue.message,\n }));\n const firstIssue = issues[0];\n const path = firstIssue?.path || '<root>';\n const message = firstIssue?.message ?? 'invalid input';\n return new NodeInputValidationError(\n `Node \"${node}\" input validation failed at \"${path}\": ${message}`,\n { node, issues },\n );\n }\n}\n\nexport class StepTimeoutError extends WorkflowError {\n readonly timeoutMs: number;\n readonly node?: string;\n\n constructor(timeoutMs: number, node?: string) {\n super(\n node\n ? `Node \"${node}\" timed out after ${timeoutMs}ms.`\n : `Step timed out after ${timeoutMs}ms.`,\n {\n code: 'STEP_TIMEOUT',\n details: { timeoutMs, ...(node === undefined ? {} : { node }) },\n },\n );\n this.timeoutMs = timeoutMs;\n this.node = node;\n }\n}\n\nexport class NodeExecutionError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string, cause: unknown) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Node \"${node}\" failed: ${causeMessage}`, {\n code: 'NODE_EXECUTION_ERROR',\n details: { node },\n cause,\n });\n this.node = node;\n }\n}\n\nexport class WorkflowLifecycleError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'WORKFLOW_LIFECYCLE_ERROR', details });\n }\n}\n\nexport class ProjectSetupError extends WorkflowError {\n constructor(cause: unknown, details: { projectName: string }) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Project \"${details.projectName}\" setup failed: ${causeMessage}`, {\n code: 'PROJECT_SETUP_ERROR',\n details,\n cause,\n });\n }\n}\n\nexport class ProjectTeardownError extends WorkflowError {\n constructor(\n cause: unknown,\n details: { projectName: string; registrationIndex: number },\n ) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Project \"${details.projectName}\" teardown failed: ${causeMessage}`, {\n code: 'PROJECT_TEARDOWN_ERROR',\n details,\n cause,\n });\n }\n}\n\nexport class NodeScopeTeardownError extends WorkflowError {\n constructor(\n cause: unknown,\n details: {\n scope: 'case' | 'document';\n scopeId: string;\n node: string;\n registrationIndex: number;\n },\n ) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(\n `${details.scope === 'case' ? 'Case attempt' : 'Workflow document'} node teardown failed for \"${details.node}\": ${causeMessage}`,\n { code: 'NODE_SCOPE_TEARDOWN_ERROR', details, cause },\n );\n }\n}\n\nexport class FatalDeviceError extends WorkflowError {\n constructor(message: string, cause?: unknown) {\n super(message, { code: 'FATAL_DEVICE_ERROR', cause });\n }\n}\n\nexport const isFatalDeviceError = (error: unknown): boolean => {\n if (error instanceof FatalDeviceError) return true;\n if (error instanceof WorkflowError && error.code === 'FATAL_DEVICE_ERROR') {\n return true;\n }\n if (\n error instanceof Error &&\n /device offline|device not found|(?:adb|bdc|device) connection (?:was )?closed/i.test(\n error.message,\n )\n ) {\n return true;\n }\n return error instanceof Error && error.cause !== undefined\n ? isFatalDeviceError(error.cause)\n : false;\n};\n\nexport class CaseExecutionError extends WorkflowError {\n readonly result: import('./engine/types').CaseRunResult;\n\n constructor(result: import('./engine/types').CaseRunResult) {\n super(`Case \"${result.name}\" failed.`, {\n code: 'CASE_EXECUTION_FAILED',\n details: { caseId: result.caseId, runId: result.runId },\n });\n this.result = result;\n }\n}\n\nexport class WorkflowDocumentExecutionError extends WorkflowError {\n readonly result: import('./engine/types').WorkflowDocumentRunResult;\n\n constructor(result: import('./engine/types').WorkflowDocumentRunResult) {\n super(`Workflow document \"${result.sourcePath}\" failed.`, {\n code: 'WORKFLOW_DOCUMENT_EXECUTION_FAILED',\n details: {\n documentId: result.documentId,\n documentRunId: result.documentRunId,\n },\n });\n this.result = result;\n }\n}\n\nexport function normalizeNodeExecutionError(\n error: unknown,\n node: string,\n): WorkflowError {\n return error instanceof WorkflowError\n ? error\n : new NodeExecutionError(node, error);\n}\n","import { z } from 'zod/v4';\nimport { NodeDefinitionError } from '../errors';\nimport type {\n DefineNodeOptions,\n DefineNodeWithSchemaOptions,\n NodeDefinition,\n NodeDefinitionWithSchema,\n NodeInputSchema,\n} from './types';\n\nconst validateOptionalText = (\n value: unknown,\n field: 'title' | 'description',\n node: string,\n): void => {\n if (\n value !== undefined &&\n (typeof value !== 'string' || value.trim().length === 0)\n ) {\n throw new NodeDefinitionError(\n `Node \"${node}\" ${field} must be a non-empty string.`,\n { node, field },\n );\n }\n};\n\nconst validateInputSchema = (schema: unknown, node: string): void => {\n if (schema === undefined) return;\n if (!(schema instanceof z.ZodObject)) {\n throw new NodeDefinitionError(\n `Node \"${node}\" inputSchema must be a Zod object schema.`,\n { node, field: 'inputSchema' },\n );\n }\n if ('$' in schema.shape) {\n throw new NodeDefinitionError(\n `Node \"${node}\" inputSchema must not declare \"$\" as an input property.`,\n { node, field: 'inputSchema.$' },\n );\n }\n};\n\nconst validateDefinition = (options: {\n name: string;\n title?: unknown;\n description?: unknown;\n stringInputKey?: unknown;\n inputSchema?: unknown;\n execute: unknown;\n}): void => {\n if (!options || typeof options !== 'object') {\n throw new NodeDefinitionError('Node definition must be an object.');\n }\n\n if (typeof options.name !== 'string' || options.name.trim().length === 0) {\n throw new NodeDefinitionError('Node name must be a non-empty string.');\n }\n\n validateOptionalText(options.title, 'title', options.name);\n validateOptionalText(options.description, 'description', options.name);\n if (\n options.stringInputKey !== undefined &&\n options.stringInputKey !== false &&\n (typeof options.stringInputKey !== 'string' ||\n options.stringInputKey.trim().length === 0)\n ) {\n throw new NodeDefinitionError(\n `Node \"${options.name}\" stringInputKey must be a non-empty string or false.`,\n { node: options.name, field: 'stringInputKey' },\n );\n }\n validateInputSchema(options.inputSchema, options.name);\n\n if (\n typeof options.stringInputKey === 'string' &&\n options.inputSchema instanceof z.ZodObject &&\n !(options.stringInputKey in options.inputSchema.shape)\n ) {\n throw new NodeDefinitionError(\n `Node \"${options.name}\" stringInputKey must reference a field in inputSchema.`,\n { node: options.name, field: 'stringInputKey' },\n );\n }\n\n if (typeof options.execute !== 'function') {\n throw new NodeDefinitionError(\n `Node \"${options.name}\" must provide an execute function.`,\n { node: options.name },\n );\n }\n};\n\nexport function defineNode<\n TSchema extends NodeInputSchema,\n TData = unknown,\n TContext = unknown,\n>(\n options: DefineNodeWithSchemaOptions<TSchema, TData, TContext>,\n): NodeDefinitionWithSchema<TSchema, TData, TContext>;\n\nexport function defineNode<\n TInput = unknown,\n TData = unknown,\n TContext = unknown,\n>(\n options: DefineNodeOptions<TInput, TData, TContext>,\n): NodeDefinition<TInput, TData, TContext>;\n\nexport function defineNode(\n options: DefineNodeOptions<any, any, any>,\n): NodeDefinition<any, any, any> {\n validateDefinition(options);\n return options;\n}\n","import {\n type AgentTestRunnerNodeDefinition,\n type AgentTestRunnerNodeProvider,\n type CommonAgentTestRunnerApi,\n aiActInputSchema,\n aiActOptionsInputSchema,\n aiAssertInputSchema,\n aiAssertOptionsInputSchema,\n aiTapInputSchema,\n insightInputSchema,\n insightOptionsInputSchema,\n locateOptionsInputSchema,\n promptImageInputSchema,\n recordToReportInputSchema,\n recordToReportOptionsInputSchema,\n reportScreenshotInputSchema,\n structuredUserPromptInputSchema,\n userPromptInputSchema,\n} from '@midscene/core/agent/test-runner';\nimport { getDebug } from '@midscene/shared/logger';\nimport { z } from 'zod/v4';\nimport type { Awaitable } from '../engine/types';\nimport { NodeDefinitionError, NodeExecutionError } from '../errors';\nimport { defineNode } from '../node/define-node';\nimport type { NodeDefinition, NodeExecutionContext } from '../node/types';\n\nexport type MidsceneUIAgent = CommonAgentTestRunnerApi & {\n addDumpUpdateListener?(\n listener: (dump: string, execution?: MidsceneExecutionRef) => void,\n ): () => void;\n};\n\nexport {\n aiActInputSchema,\n aiActOptionsInputSchema,\n aiAssertInputSchema,\n aiAssertOptionsInputSchema,\n aiTapInputSchema,\n insightInputSchema,\n insightOptionsInputSchema,\n locateOptionsInputSchema,\n promptImageInputSchema,\n recordToReportInputSchema,\n recordToReportOptionsInputSchema,\n reportScreenshotInputSchema,\n structuredUserPromptInputSchema,\n userPromptInputSchema,\n};\n\nexport interface MidsceneExecutionRef {\n id?: string;\n}\n\nexport interface AgentProvider<TContext> {\n getAgent(\n runId: string,\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Awaitable<MidsceneUIAgent>;\n // biome-ignore lint/suspicious/noConfusingVoidType: providers without a report intentionally return void.\n releaseAgent?(runId: string): Awaitable<AgentReleaseResult | void>;\n dispose?(): Awaitable<void>;\n}\n\nexport interface AgentReleaseResult {\n /** Absolute path to the finalized report for this Agent scope. */\n reportPath?: string;\n}\n\nexport const waitInputSchema = z.strictObject({\n duration: z.number().positive().describe('How long to wait.'),\n unit: z\n .enum(['ms', 's', 'min'])\n .default('ms')\n .describe('Duration unit: milliseconds, seconds, or minutes.'),\n});\n\nexport type AiActNodeInput = z.infer<typeof aiActInputSchema>;\nexport type AiAssertNodeInput = z.infer<typeof aiAssertInputSchema>;\nexport type AiTapNodeInput = z.infer<typeof aiTapInputSchema>;\nexport type InsightNodeInput = z.infer<typeof insightInputSchema>;\nexport type RecordToReportNodeInput = z.infer<typeof recordToReportInputSchema>;\nexport type WaitNodeInput = z.infer<typeof waitInputSchema>;\n\nexport interface CreateMidsceneNodesOptions<TContext> {\n getAgent?(\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Awaitable<MidsceneUIAgent>;\n agentProvider?: AgentProvider<TContext>;\n /** Agent class that declares the Agent-backed Nodes to register. */\n agentClass: AgentTestRunnerNodeProvider;\n}\n\nconst waitFor = async (durationMs: number, signal: AbortSignal) => {\n if (signal.aborted) {\n throw signal.reason ?? new Error('Wait aborted.');\n }\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n signal.removeEventListener('abort', abort);\n resolve();\n }, durationMs);\n const abort = () => {\n clearTimeout(timeout);\n reject(signal.reason ?? new Error('Wait aborted.'));\n };\n signal.addEventListener('abort', abort, { once: true });\n });\n};\n\n/** Adapt Agent-owned descriptions to executable Midscene Test Nodes. */\nexport const createAgentTestRunnerNodes = <TContext>(\n definitions: readonly AgentTestRunnerNodeDefinition[],\n getAgent: (\n ctx: NodeExecutionContext<unknown, TContext>,\n ) => Awaitable<unknown>,\n): readonly NodeDefinition<any, any, TContext>[] => {\n const activeAgentCalls = new WeakMap<\n MidsceneUIAgent,\n { scopeId: string; node: string }\n >();\n const runAgentCall = async <T>(\n node: string,\n ctx: NodeExecutionContext<unknown, TContext>,\n agent: MidsceneUIAgent,\n call: () => Promise<T>,\n captureExecutions = true,\n ): Promise<T> => {\n const scopeId =\n ctx.scope === 'case' ? ctx.case.runId : ctx.document.documentRunId;\n const activeCall = activeAgentCalls.get(agent);\n if (activeCall) {\n throw new NodeExecutionError(\n node,\n new Error(\n `The same Agent instance cannot execute overlapping Midscene Test Steps. Active scope: ${activeCall.scopeId} (${activeCall.node}); requested scope: ${scopeId} (${node}).`,\n ),\n );\n }\n\n activeAgentCalls.set(agent, { scopeId, node });\n let removeListener: (() => void) | undefined;\n let sawExecutionWithoutId = false;\n const stopListening = () => {\n const remove = removeListener;\n removeListener = undefined;\n remove?.();\n };\n const stopListeningOnAbort = () => stopListening();\n try {\n if (captureExecutions && agent.addDumpUpdateListener) {\n removeListener = agent.addDumpUpdateListener((_dump, execution) => {\n if (!execution) return;\n if (!execution.id) {\n sawExecutionWithoutId = true;\n return;\n }\n ctx.report.addTrace({\n type: 'midscene-execution',\n executionId: execution.id,\n });\n });\n if (ctx.signal.aborted) stopListening();\n else {\n ctx.signal.addEventListener('abort', stopListeningOnAbort, {\n once: true,\n });\n }\n }\n return await call();\n } finally {\n ctx.signal.removeEventListener('abort', stopListeningOnAbort);\n try {\n stopListening();\n } finally {\n activeAgentCalls.delete(agent);\n }\n if (sawExecutionWithoutId) {\n warnReportTrace(\n `Skipped a report trace without a stable execution id for ${node} in scope ${scopeId}.`,\n );\n }\n }\n };\n\n return definitions.map((definition) =>\n defineNode({\n name: definition.name,\n ...(definition.title === undefined ? {} : { title: definition.title }),\n ...(definition.description === undefined\n ? {}\n : { description: definition.description }),\n ...(definition.stringInputKey === undefined\n ? {}\n : { stringInputKey: definition.stringInputKey }),\n inputSchema: definition.inputSchema,\n async execute(ctx) {\n const agent = await getAgent(ctx);\n const call = async () =>\n definition.execute(agent, ctx.input, { signal: ctx.signal });\n if (typeof agent !== 'object' || agent === null) return call();\n return runAgentCall(\n definition.name,\n ctx,\n agent as MidsceneUIAgent,\n call,\n );\n },\n }),\n );\n};\n\nconst warnReportTrace = getDebug('test-runner:report-trace', {\n console: true,\n});\n\nexport function createMidsceneNodes<TContext>(\n options: CreateMidsceneNodesOptions<TContext>,\n): readonly NodeDefinition<any, any, TContext>[] {\n if (!options || typeof options !== 'object') {\n throw new NodeDefinitionError(\n 'createMidsceneNodes() options must be an object.',\n );\n }\n if (\n typeof options.agentProvider?.getAgent !== 'function' &&\n typeof options.getAgent !== 'function'\n ) {\n throw new NodeDefinitionError(\n 'createMidsceneNodes() requires getAgent or agentProvider.getAgent.',\n );\n }\n if (\n !options.agentClass ||\n typeof options.agentClass.getTestRunnerNodeDefinitions !== 'function'\n ) {\n throw new NodeDefinitionError(\n 'createMidsceneNodes() requires agentClass.getTestRunnerNodeDefinitions().',\n );\n }\n\n const registeredAgentScopes = new Set<string>();\n const getExecutionId = (ctx: NodeExecutionContext<unknown, TContext>) =>\n ctx.scope === 'case' ? ctx.case.runId : ctx.document.documentRunId;\n const getAgent = async (\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Promise<MidsceneUIAgent> => {\n if (!options.agentProvider) return options.getAgent!(ctx);\n const runId = getExecutionId(ctx);\n if (\n options.agentProvider.releaseAgent &&\n !registeredAgentScopes.has(runId)\n ) {\n registeredAgentScopes.add(runId);\n ctx.onTeardown(async () => {\n try {\n const released = await options.agentProvider!.releaseAgent!(runId);\n return released?.reportPath\n ? { reportPaths: [released.reportPath] }\n : undefined;\n } finally {\n registeredAgentScopes.delete(runId);\n }\n });\n }\n return options.agentProvider.getAgent(runId, ctx);\n };\n\n const agentDefinitions = options.agentClass.getTestRunnerNodeDefinitions();\n\n return [\n ...createAgentTestRunnerNodes(agentDefinitions, getAgent),\n defineNode<typeof waitInputSchema, unknown, TContext>({\n name: 'wait',\n description: 'Wait for a fixed duration while honoring cancellation.',\n stringInputKey: false,\n inputSchema: waitInputSchema,\n async execute(ctx) {\n const multiplier =\n ctx.input.unit === 'min'\n ? 60_000\n : ctx.input.unit === 's'\n ? 1_000\n : 1;\n const durationMs = ctx.input.duration * multiplier;\n await waitFor(durationMs, ctx.signal);\n return { summary: `Waited ${durationMs}ms` };\n },\n }),\n ];\n}\n","__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 type { IOSAgent } from '@midscene/ios';\nimport {\n iosAgentTestRunnerNodeDefinitions,\n launchInputSchema,\n runWdaRequestInputSchema,\n terminateInputSchema,\n wdaRequestInputSchema,\n} from '@midscene/ios/test-runner';\nexport type {\n LaunchNodeInput,\n RunWdaRequestNodeInput,\n TerminateNodeInput,\n WDAHttpMethod,\n} from '@midscene/ios/test-runner';\nimport type { Awaitable } from '../engine/types';\nimport { NodeDefinitionError } from '../errors';\nimport { createAgentTestRunnerNodes } from '../midscene';\nimport type { NodeDefinition, NodeExecutionContext } from '../node/types';\n\nexport {\n launchInputSchema,\n runWdaRequestInputSchema,\n terminateInputSchema,\n wdaRequestInputSchema,\n};\n\nexport type IOSRunnerAgent = Pick<\n IOSAgent,\n 'launch' | 'terminate' | 'runWdaRequest' | 'home' | 'appSwitcher'\n>;\n\nexport interface CreateIOSNodesOptions<TContext> {\n getAgent(\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Awaitable<IOSRunnerAgent>;\n}\n\nexport function createIOSNodes<TContext>(\n options: CreateIOSNodesOptions<TContext>,\n): readonly NodeDefinition<any, any, TContext>[] {\n if (!options || typeof options !== 'object') {\n throw new NodeDefinitionError(\n 'createIOSNodes() options must be an object.',\n );\n }\n if (typeof options.getAgent !== 'function') {\n throw new NodeDefinitionError('createIOSNodes() requires getAgent().');\n }\n\n return createAgentTestRunnerNodes(\n iosAgentTestRunnerNodeDefinitions,\n options.getAgent,\n );\n}\n"],"names":["WorkflowError","Error","undefined","message","options","NodeDefinitionError","details","NodeExecutionError","node","cause","causeMessage","String","validateOptionalText","value","field","validateInputSchema","schema","z","validateDefinition","defineNode","createAgentTestRunnerNodes","definitions","getAgent","activeAgentCalls","WeakMap","runAgentCall","ctx","agent","call","captureExecutions","scopeId","activeCall","removeListener","sawExecutionWithoutId","stopListening","remove","stopListeningOnAbort","_dump","execution","warnReportTrace","definition","getDebug","__webpack_require__","key","Object","obj","prop","Symbol","createIOSNodes","iosAgentTestRunnerNodeDefinitions"],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
var __webpack_modules__ = {
|
|
3
3
|
"./src/errors.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
4
4
|
__webpack_require__.d(__webpack_exports__, {
|
|
5
|
+
h2: ()=>NodeExecutionError,
|
|
5
6
|
ww: ()=>NodeDefinitionError
|
|
6
7
|
});
|
|
7
8
|
function _define_property(obj, key, value) {
|
|
@@ -42,6 +43,19 @@ var __webpack_modules__ = {
|
|
|
42
43
|
});
|
|
43
44
|
}
|
|
44
45
|
}
|
|
46
|
+
class NodeExecutionError extends WorkflowError {
|
|
47
|
+
constructor(node, cause){
|
|
48
|
+
const causeMessage = cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');
|
|
49
|
+
super(`Node "${node}" failed: ${causeMessage}`, {
|
|
50
|
+
code: 'NODE_EXECUTION_ERROR',
|
|
51
|
+
details: {
|
|
52
|
+
node
|
|
53
|
+
},
|
|
54
|
+
cause
|
|
55
|
+
}), _define_property(this, "node", void 0);
|
|
56
|
+
this.node = node;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
45
59
|
}
|
|
46
60
|
};
|
|
47
61
|
var __webpack_module_cache__ = {};
|
|
@@ -98,6 +112,7 @@ var __webpack_exports__ = {};
|
|
|
98
112
|
insightOptionsInputSchema: ()=>test_runner_namespaceObject.insightOptionsInputSchema
|
|
99
113
|
});
|
|
100
114
|
const test_runner_namespaceObject = require("@midscene/core/agent/test-runner");
|
|
115
|
+
const logger_namespaceObject = require("@midscene/shared/logger");
|
|
101
116
|
const v4_namespaceObject = require("zod/v4");
|
|
102
117
|
var errors = __webpack_require__("./src/errors.ts");
|
|
103
118
|
const validateOptionalText = (value, field, node)=>{
|
|
@@ -163,7 +178,54 @@ var __webpack_exports__ = {};
|
|
|
163
178
|
});
|
|
164
179
|
});
|
|
165
180
|
};
|
|
166
|
-
const createAgentTestRunnerNodes = (definitions, getAgent)=>
|
|
181
|
+
const createAgentTestRunnerNodes = (definitions, getAgent)=>{
|
|
182
|
+
const activeAgentCalls = new WeakMap();
|
|
183
|
+
const runAgentCall = async (node, ctx, agent, call, captureExecutions = true)=>{
|
|
184
|
+
const scopeId = 'case' === ctx.scope ? ctx.case.runId : ctx.document.documentRunId;
|
|
185
|
+
const activeCall = activeAgentCalls.get(agent);
|
|
186
|
+
if (activeCall) throw new errors.h2(node, new Error(`The same Agent instance cannot execute overlapping Midscene Test Steps. Active scope: ${activeCall.scopeId} (${activeCall.node}); requested scope: ${scopeId} (${node}).`));
|
|
187
|
+
activeAgentCalls.set(agent, {
|
|
188
|
+
scopeId,
|
|
189
|
+
node
|
|
190
|
+
});
|
|
191
|
+
let removeListener;
|
|
192
|
+
let sawExecutionWithoutId = false;
|
|
193
|
+
const stopListening = ()=>{
|
|
194
|
+
const remove = removeListener;
|
|
195
|
+
removeListener = void 0;
|
|
196
|
+
remove?.();
|
|
197
|
+
};
|
|
198
|
+
const stopListeningOnAbort = ()=>stopListening();
|
|
199
|
+
try {
|
|
200
|
+
if (captureExecutions && agent.addDumpUpdateListener) {
|
|
201
|
+
removeListener = agent.addDumpUpdateListener((_dump, execution)=>{
|
|
202
|
+
if (!execution) return;
|
|
203
|
+
if (!execution.id) {
|
|
204
|
+
sawExecutionWithoutId = true;
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
ctx.report.addTrace({
|
|
208
|
+
type: 'midscene-execution',
|
|
209
|
+
executionId: execution.id
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
if (ctx.signal.aborted) stopListening();
|
|
213
|
+
else ctx.signal.addEventListener('abort', stopListeningOnAbort, {
|
|
214
|
+
once: true
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
return await call();
|
|
218
|
+
} finally{
|
|
219
|
+
ctx.signal.removeEventListener('abort', stopListeningOnAbort);
|
|
220
|
+
try {
|
|
221
|
+
stopListening();
|
|
222
|
+
} finally{
|
|
223
|
+
activeAgentCalls.delete(agent);
|
|
224
|
+
}
|
|
225
|
+
if (sawExecutionWithoutId) warnReportTrace(`Skipped a report trace without a stable execution id for ${node} in scope ${scopeId}.`);
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
return definitions.map((definition)=>defineNode({
|
|
167
229
|
name: definition.name,
|
|
168
230
|
...void 0 === definition.title ? {} : {
|
|
169
231
|
title: definition.title
|
|
@@ -177,11 +239,17 @@ var __webpack_exports__ = {};
|
|
|
177
239
|
inputSchema: definition.inputSchema,
|
|
178
240
|
async execute (ctx) {
|
|
179
241
|
const agent = await getAgent(ctx);
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
242
|
+
const call = async ()=>definition.execute(agent, ctx.input, {
|
|
243
|
+
signal: ctx.signal
|
|
244
|
+
});
|
|
245
|
+
if ('object' != typeof agent || null === agent) return call();
|
|
246
|
+
return runAgentCall(definition.name, ctx, agent, call);
|
|
183
247
|
}
|
|
184
248
|
}));
|
|
249
|
+
};
|
|
250
|
+
const warnReportTrace = (0, logger_namespaceObject.getDebug)('test-runner:report-trace', {
|
|
251
|
+
console: true
|
|
252
|
+
});
|
|
185
253
|
function createMidsceneNodes(options) {
|
|
186
254
|
if (!options || 'object' != typeof options) throw new errors.ww('createMidsceneNodes() options must be an object.');
|
|
187
255
|
if ('function' != typeof options.agentProvider?.getAgent && 'function' != typeof options.getAgent) throw new errors.ww('createMidsceneNodes() requires getAgent or agentProvider.getAgent.');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midscene/index.js","sources":["../../../src/errors.ts","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/node/define-node.ts","../../../src/midscene/index.ts"],"sourcesContent":["import type { z } from 'zod/v4';\n\nexport interface WorkflowErrorOptions {\n code?: string;\n details?: unknown;\n cause?: unknown;\n}\n\nexport class WorkflowError extends Error {\n readonly code: string;\n readonly details?: unknown;\n\n constructor(message: string, options: WorkflowErrorOptions = {}) {\n super(message, { cause: options.cause });\n this.name = new.target.name;\n this.code = options.code ?? 'WORKFLOW_ERROR';\n this.details = options.details;\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n ...(this.details === undefined ? {} : { details: this.details }),\n };\n }\n}\n\nexport class WorkflowParseError extends WorkflowError {\n constructor(message: string, details?: unknown, cause?: unknown) {\n super(message, { code: 'WORKFLOW_PARSE_ERROR', details, cause });\n }\n}\n\nexport class NodeDefinitionError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'NODE_DEFINITION_ERROR', details });\n }\n}\n\nexport class DuplicateNodeError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string) {\n super(`Node \"${node}\" is already registered.`, {\n code: 'DUPLICATE_NODE',\n details: { node },\n });\n this.node = node;\n }\n}\n\nexport class NodeNotFoundError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string) {\n super(`Node \"${node}\" is not registered.`, {\n code: 'NODE_NOT_FOUND',\n details: { node },\n });\n this.node = node;\n }\n}\n\nexport class NodeInputValidationError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'NODE_INPUT_VALIDATION_ERROR', details });\n }\n\n static fromZod(node: string, error: z.ZodError): NodeInputValidationError {\n const issues = error.issues.map((issue) => ({\n code: issue.code,\n path: issue.path.map(String).join('.'),\n message: issue.message,\n }));\n const firstIssue = issues[0];\n const path = firstIssue?.path || '<root>';\n const message = firstIssue?.message ?? 'invalid input';\n return new NodeInputValidationError(\n `Node \"${node}\" input validation failed at \"${path}\": ${message}`,\n { node, issues },\n );\n }\n}\n\nexport class StepTimeoutError extends WorkflowError {\n readonly timeoutMs: number;\n readonly node?: string;\n\n constructor(timeoutMs: number, node?: string) {\n super(\n node\n ? `Node \"${node}\" timed out after ${timeoutMs}ms.`\n : `Step timed out after ${timeoutMs}ms.`,\n {\n code: 'STEP_TIMEOUT',\n details: { timeoutMs, ...(node === undefined ? {} : { node }) },\n },\n );\n this.timeoutMs = timeoutMs;\n this.node = node;\n }\n}\n\nexport class NodeExecutionError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string, cause: unknown) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Node \"${node}\" failed: ${causeMessage}`, {\n code: 'NODE_EXECUTION_ERROR',\n details: { node },\n cause,\n });\n this.node = node;\n }\n}\n\nexport class WorkflowLifecycleError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'WORKFLOW_LIFECYCLE_ERROR', details });\n }\n}\n\nexport class ProjectSetupError extends WorkflowError {\n constructor(cause: unknown, details: { projectName: string }) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Project \"${details.projectName}\" setup failed: ${causeMessage}`, {\n code: 'PROJECT_SETUP_ERROR',\n details,\n cause,\n });\n }\n}\n\nexport class ProjectTeardownError extends WorkflowError {\n constructor(\n cause: unknown,\n details: { projectName: string; registrationIndex: number },\n ) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Project \"${details.projectName}\" teardown failed: ${causeMessage}`, {\n code: 'PROJECT_TEARDOWN_ERROR',\n details,\n cause,\n });\n }\n}\n\nexport class NodeScopeTeardownError extends WorkflowError {\n constructor(\n cause: unknown,\n details: {\n scope: 'case' | 'document';\n scopeId: string;\n node: string;\n registrationIndex: number;\n },\n ) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(\n `${details.scope === 'case' ? 'Case attempt' : 'Workflow document'} node teardown failed for \"${details.node}\": ${causeMessage}`,\n { code: 'NODE_SCOPE_TEARDOWN_ERROR', details, cause },\n );\n }\n}\n\nexport class FatalDeviceError extends WorkflowError {\n constructor(message: string, cause?: unknown) {\n super(message, { code: 'FATAL_DEVICE_ERROR', cause });\n }\n}\n\nexport const isFatalDeviceError = (error: unknown): boolean => {\n if (error instanceof FatalDeviceError) return true;\n if (error instanceof WorkflowError && error.code === 'FATAL_DEVICE_ERROR') {\n return true;\n }\n if (\n error instanceof Error &&\n /device offline|device not found|(?:adb|bdc|device) connection (?:was )?closed/i.test(\n error.message,\n )\n ) {\n return true;\n }\n return error instanceof Error && error.cause !== undefined\n ? isFatalDeviceError(error.cause)\n : false;\n};\n\nexport class CaseExecutionError extends WorkflowError {\n readonly result: import('./engine/types').CaseRunResult;\n\n constructor(result: import('./engine/types').CaseRunResult) {\n super(`Case \"${result.name}\" failed.`, {\n code: 'CASE_EXECUTION_FAILED',\n details: { caseId: result.caseId, runId: result.runId },\n });\n this.result = result;\n }\n}\n\nexport class WorkflowDocumentExecutionError extends WorkflowError {\n readonly result: import('./engine/types').WorkflowDocumentRunResult;\n\n constructor(result: import('./engine/types').WorkflowDocumentRunResult) {\n super(`Workflow document \"${result.sourcePath}\" failed.`, {\n code: 'WORKFLOW_DOCUMENT_EXECUTION_FAILED',\n details: {\n documentId: result.documentId,\n documentRunId: result.documentRunId,\n },\n });\n this.result = result;\n }\n}\n\nexport function normalizeNodeExecutionError(\n error: unknown,\n node: string,\n): WorkflowError {\n return error instanceof WorkflowError\n ? error\n : new NodeExecutionError(node, error);\n}\n","__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 { z } from 'zod/v4';\nimport { NodeDefinitionError } from '../errors';\nimport type {\n DefineNodeOptions,\n DefineNodeWithSchemaOptions,\n NodeDefinition,\n NodeDefinitionWithSchema,\n NodeInputSchema,\n} from './types';\n\nconst validateOptionalText = (\n value: unknown,\n field: 'title' | 'description',\n node: string,\n): void => {\n if (\n value !== undefined &&\n (typeof value !== 'string' || value.trim().length === 0)\n ) {\n throw new NodeDefinitionError(\n `Node \"${node}\" ${field} must be a non-empty string.`,\n { node, field },\n );\n }\n};\n\nconst validateInputSchema = (schema: unknown, node: string): void => {\n if (schema === undefined) return;\n if (!(schema instanceof z.ZodObject)) {\n throw new NodeDefinitionError(\n `Node \"${node}\" inputSchema must be a Zod object schema.`,\n { node, field: 'inputSchema' },\n );\n }\n if ('$' in schema.shape) {\n throw new NodeDefinitionError(\n `Node \"${node}\" inputSchema must not declare \"$\" as an input property.`,\n { node, field: 'inputSchema.$' },\n );\n }\n};\n\nconst validateDefinition = (options: {\n name: string;\n title?: unknown;\n description?: unknown;\n stringInputKey?: unknown;\n inputSchema?: unknown;\n execute: unknown;\n}): void => {\n if (!options || typeof options !== 'object') {\n throw new NodeDefinitionError('Node definition must be an object.');\n }\n\n if (typeof options.name !== 'string' || options.name.trim().length === 0) {\n throw new NodeDefinitionError('Node name must be a non-empty string.');\n }\n\n validateOptionalText(options.title, 'title', options.name);\n validateOptionalText(options.description, 'description', options.name);\n if (\n options.stringInputKey !== undefined &&\n options.stringInputKey !== false &&\n (typeof options.stringInputKey !== 'string' ||\n options.stringInputKey.trim().length === 0)\n ) {\n throw new NodeDefinitionError(\n `Node \"${options.name}\" stringInputKey must be a non-empty string or false.`,\n { node: options.name, field: 'stringInputKey' },\n );\n }\n validateInputSchema(options.inputSchema, options.name);\n\n if (\n typeof options.stringInputKey === 'string' &&\n options.inputSchema instanceof z.ZodObject &&\n !(options.stringInputKey in options.inputSchema.shape)\n ) {\n throw new NodeDefinitionError(\n `Node \"${options.name}\" stringInputKey must reference a field in inputSchema.`,\n { node: options.name, field: 'stringInputKey' },\n );\n }\n\n if (typeof options.execute !== 'function') {\n throw new NodeDefinitionError(\n `Node \"${options.name}\" must provide an execute function.`,\n { node: options.name },\n );\n }\n};\n\nexport function defineNode<\n TSchema extends NodeInputSchema,\n TData = unknown,\n TContext = unknown,\n>(\n options: DefineNodeWithSchemaOptions<TSchema, TData, TContext>,\n): NodeDefinitionWithSchema<TSchema, TData, TContext>;\n\nexport function defineNode<\n TInput = unknown,\n TData = unknown,\n TContext = unknown,\n>(\n options: DefineNodeOptions<TInput, TData, TContext>,\n): NodeDefinition<TInput, TData, TContext>;\n\nexport function defineNode(\n options: DefineNodeOptions<any, any, any>,\n): NodeDefinition<any, any, any> {\n validateDefinition(options);\n return options;\n}\n","import {\n type AgentTestRunnerNodeDefinition,\n type AgentTestRunnerNodeProvider,\n type CommonAgentTestRunnerApi,\n aiActInputSchema,\n aiActOptionsInputSchema,\n aiAssertInputSchema,\n aiAssertOptionsInputSchema,\n aiTapInputSchema,\n insightInputSchema,\n insightOptionsInputSchema,\n locateOptionsInputSchema,\n promptImageInputSchema,\n recordToReportInputSchema,\n recordToReportOptionsInputSchema,\n reportScreenshotInputSchema,\n structuredUserPromptInputSchema,\n userPromptInputSchema,\n} from '@midscene/core/agent/test-runner';\nimport { z } from 'zod/v4';\nimport type { Awaitable } from '../engine/types';\nimport { NodeDefinitionError } from '../errors';\nimport { defineNode } from '../node/define-node';\nimport type { NodeDefinition, NodeExecutionContext } from '../node/types';\n\nexport type MidsceneUIAgent = CommonAgentTestRunnerApi;\n\nexport {\n aiActInputSchema,\n aiActOptionsInputSchema,\n aiAssertInputSchema,\n aiAssertOptionsInputSchema,\n aiTapInputSchema,\n insightInputSchema,\n insightOptionsInputSchema,\n locateOptionsInputSchema,\n promptImageInputSchema,\n recordToReportInputSchema,\n recordToReportOptionsInputSchema,\n reportScreenshotInputSchema,\n structuredUserPromptInputSchema,\n userPromptInputSchema,\n};\n\nexport interface AgentProvider<TContext> {\n getAgent(\n runId: string,\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Awaitable<MidsceneUIAgent>;\n // biome-ignore lint/suspicious/noConfusingVoidType: providers without a report intentionally return void.\n releaseAgent?(runId: string): Awaitable<AgentReleaseResult | void>;\n dispose?(): Awaitable<void>;\n}\n\nexport interface AgentReleaseResult {\n /** Absolute path to the finalized report for this Agent scope. */\n reportPath?: string;\n}\n\nexport const waitInputSchema = z.strictObject({\n duration: z.number().positive().describe('How long to wait.'),\n unit: z\n .enum(['ms', 's', 'min'])\n .default('ms')\n .describe('Duration unit: milliseconds, seconds, or minutes.'),\n});\n\nexport type AiActNodeInput = z.infer<typeof aiActInputSchema>;\nexport type AiAssertNodeInput = z.infer<typeof aiAssertInputSchema>;\nexport type AiTapNodeInput = z.infer<typeof aiTapInputSchema>;\nexport type InsightNodeInput = z.infer<typeof insightInputSchema>;\nexport type RecordToReportNodeInput = z.infer<typeof recordToReportInputSchema>;\nexport type WaitNodeInput = z.infer<typeof waitInputSchema>;\n\nexport interface CreateMidsceneNodesOptions<TContext> {\n getAgent?(\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Awaitable<MidsceneUIAgent>;\n agentProvider?: AgentProvider<TContext>;\n /** Agent class that declares the Agent-backed Nodes to register. */\n agentClass: AgentTestRunnerNodeProvider;\n}\n\nconst waitFor = async (durationMs: number, signal: AbortSignal) => {\n if (signal.aborted) {\n throw signal.reason ?? new Error('Wait aborted.');\n }\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n signal.removeEventListener('abort', abort);\n resolve();\n }, durationMs);\n const abort = () => {\n clearTimeout(timeout);\n reject(signal.reason ?? new Error('Wait aborted.'));\n };\n signal.addEventListener('abort', abort, { once: true });\n });\n};\n\n/** Adapt Agent-owned descriptions to executable Midscene Test Nodes. */\nexport const createAgentTestRunnerNodes = <TContext>(\n definitions: readonly AgentTestRunnerNodeDefinition[],\n getAgent: (\n ctx: NodeExecutionContext<unknown, TContext>,\n ) => Awaitable<unknown>,\n): readonly NodeDefinition<any, any, TContext>[] =>\n definitions.map((definition) =>\n defineNode({\n name: definition.name,\n ...(definition.title === undefined ? {} : { title: definition.title }),\n ...(definition.description === undefined\n ? {}\n : { description: definition.description }),\n ...(definition.stringInputKey === undefined\n ? {}\n : { stringInputKey: definition.stringInputKey }),\n inputSchema: definition.inputSchema,\n async execute(ctx) {\n const agent = await getAgent(ctx);\n return definition.execute(agent, ctx.input, {\n signal: ctx.signal,\n });\n },\n }),\n );\n\nexport function createMidsceneNodes<TContext>(\n options: CreateMidsceneNodesOptions<TContext>,\n): readonly NodeDefinition<any, any, TContext>[] {\n if (!options || typeof options !== 'object') {\n throw new NodeDefinitionError(\n 'createMidsceneNodes() options must be an object.',\n );\n }\n if (\n typeof options.agentProvider?.getAgent !== 'function' &&\n typeof options.getAgent !== 'function'\n ) {\n throw new NodeDefinitionError(\n 'createMidsceneNodes() requires getAgent or agentProvider.getAgent.',\n );\n }\n if (\n !options.agentClass ||\n typeof options.agentClass.getTestRunnerNodeDefinitions !== 'function'\n ) {\n throw new NodeDefinitionError(\n 'createMidsceneNodes() requires agentClass.getTestRunnerNodeDefinitions().',\n );\n }\n\n const registeredAgentScopes = new Set<string>();\n const getExecutionId = (ctx: NodeExecutionContext<unknown, TContext>) =>\n ctx.scope === 'case' ? ctx.case.runId : ctx.document.documentRunId;\n const getAgent = async (\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Promise<MidsceneUIAgent> => {\n if (!options.agentProvider) return options.getAgent!(ctx);\n const runId = getExecutionId(ctx);\n if (\n options.agentProvider.releaseAgent &&\n !registeredAgentScopes.has(runId)\n ) {\n registeredAgentScopes.add(runId);\n ctx.onTeardown(async () => {\n try {\n const released = await options.agentProvider!.releaseAgent!(runId);\n return released?.reportPath\n ? { reportPaths: [released.reportPath] }\n : undefined;\n } finally {\n registeredAgentScopes.delete(runId);\n }\n });\n }\n return options.agentProvider.getAgent(runId, ctx);\n };\n\n const agentDefinitions = options.agentClass.getTestRunnerNodeDefinitions();\n\n return [\n ...createAgentTestRunnerNodes(agentDefinitions, getAgent),\n defineNode<typeof waitInputSchema, unknown, TContext>({\n name: 'wait',\n description: 'Wait for a fixed duration while honoring cancellation.',\n stringInputKey: false,\n inputSchema: waitInputSchema,\n async execute(ctx) {\n const multiplier =\n ctx.input.unit === 'min'\n ? 60_000\n : ctx.input.unit === 's'\n ? 1_000\n : 1;\n const durationMs = ctx.input.duration * multiplier;\n await waitFor(durationMs, ctx.signal);\n return { summary: `Waited ${durationMs}ms` };\n },\n }),\n ];\n}\n"],"names":["WorkflowError","Error","undefined","message","options","NodeDefinitionError","details","__webpack_require__","definition","key","Object","obj","prop","Symbol","validateOptionalText","value","field","node","validateInputSchema","schema","z","validateDefinition","defineNode","waitInputSchema","waitFor","durationMs","signal","Promise","resolve","reject","timeout","setTimeout","abort","clearTimeout","createAgentTestRunnerNodes","definitions","getAgent","ctx","agent","createMidsceneNodes","registeredAgentScopes","Set","getExecutionId","runId","released","agentDefinitions","multiplier"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"midscene/index.js","sources":["../../../src/errors.ts","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/node/define-node.ts","../../../src/midscene/index.ts"],"sourcesContent":["import type { z } from 'zod/v4';\n\nexport interface WorkflowErrorOptions {\n code?: string;\n details?: unknown;\n cause?: unknown;\n}\n\nexport class WorkflowError extends Error {\n readonly code: string;\n readonly details?: unknown;\n\n constructor(message: string, options: WorkflowErrorOptions = {}) {\n super(message, { cause: options.cause });\n this.name = new.target.name;\n this.code = options.code ?? 'WORKFLOW_ERROR';\n this.details = options.details;\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n ...(this.details === undefined ? {} : { details: this.details }),\n };\n }\n}\n\nexport class WorkflowParseError extends WorkflowError {\n constructor(message: string, details?: unknown, cause?: unknown) {\n super(message, { code: 'WORKFLOW_PARSE_ERROR', details, cause });\n }\n}\n\nexport class NodeDefinitionError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'NODE_DEFINITION_ERROR', details });\n }\n}\n\nexport class DuplicateNodeError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string) {\n super(`Node \"${node}\" is already registered.`, {\n code: 'DUPLICATE_NODE',\n details: { node },\n });\n this.node = node;\n }\n}\n\nexport class NodeNotFoundError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string) {\n super(`Node \"${node}\" is not registered.`, {\n code: 'NODE_NOT_FOUND',\n details: { node },\n });\n this.node = node;\n }\n}\n\nexport class NodeInputValidationError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'NODE_INPUT_VALIDATION_ERROR', details });\n }\n\n static fromZod(node: string, error: z.ZodError): NodeInputValidationError {\n const issues = error.issues.map((issue) => ({\n code: issue.code,\n path: issue.path.map(String).join('.'),\n message: issue.message,\n }));\n const firstIssue = issues[0];\n const path = firstIssue?.path || '<root>';\n const message = firstIssue?.message ?? 'invalid input';\n return new NodeInputValidationError(\n `Node \"${node}\" input validation failed at \"${path}\": ${message}`,\n { node, issues },\n );\n }\n}\n\nexport class StepTimeoutError extends WorkflowError {\n readonly timeoutMs: number;\n readonly node?: string;\n\n constructor(timeoutMs: number, node?: string) {\n super(\n node\n ? `Node \"${node}\" timed out after ${timeoutMs}ms.`\n : `Step timed out after ${timeoutMs}ms.`,\n {\n code: 'STEP_TIMEOUT',\n details: { timeoutMs, ...(node === undefined ? {} : { node }) },\n },\n );\n this.timeoutMs = timeoutMs;\n this.node = node;\n }\n}\n\nexport class NodeExecutionError extends WorkflowError {\n readonly node: string;\n\n constructor(node: string, cause: unknown) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Node \"${node}\" failed: ${causeMessage}`, {\n code: 'NODE_EXECUTION_ERROR',\n details: { node },\n cause,\n });\n this.node = node;\n }\n}\n\nexport class WorkflowLifecycleError extends WorkflowError {\n constructor(message: string, details?: unknown) {\n super(message, { code: 'WORKFLOW_LIFECYCLE_ERROR', details });\n }\n}\n\nexport class ProjectSetupError extends WorkflowError {\n constructor(cause: unknown, details: { projectName: string }) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Project \"${details.projectName}\" setup failed: ${causeMessage}`, {\n code: 'PROJECT_SETUP_ERROR',\n details,\n cause,\n });\n }\n}\n\nexport class ProjectTeardownError extends WorkflowError {\n constructor(\n cause: unknown,\n details: { projectName: string; registrationIndex: number },\n ) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(`Project \"${details.projectName}\" teardown failed: ${causeMessage}`, {\n code: 'PROJECT_TEARDOWN_ERROR',\n details,\n cause,\n });\n }\n}\n\nexport class NodeScopeTeardownError extends WorkflowError {\n constructor(\n cause: unknown,\n details: {\n scope: 'case' | 'document';\n scopeId: string;\n node: string;\n registrationIndex: number;\n },\n ) {\n const causeMessage =\n cause instanceof Error ? cause.message : String(cause ?? 'Unknown error');\n super(\n `${details.scope === 'case' ? 'Case attempt' : 'Workflow document'} node teardown failed for \"${details.node}\": ${causeMessage}`,\n { code: 'NODE_SCOPE_TEARDOWN_ERROR', details, cause },\n );\n }\n}\n\nexport class FatalDeviceError extends WorkflowError {\n constructor(message: string, cause?: unknown) {\n super(message, { code: 'FATAL_DEVICE_ERROR', cause });\n }\n}\n\nexport const isFatalDeviceError = (error: unknown): boolean => {\n if (error instanceof FatalDeviceError) return true;\n if (error instanceof WorkflowError && error.code === 'FATAL_DEVICE_ERROR') {\n return true;\n }\n if (\n error instanceof Error &&\n /device offline|device not found|(?:adb|bdc|device) connection (?:was )?closed/i.test(\n error.message,\n )\n ) {\n return true;\n }\n return error instanceof Error && error.cause !== undefined\n ? isFatalDeviceError(error.cause)\n : false;\n};\n\nexport class CaseExecutionError extends WorkflowError {\n readonly result: import('./engine/types').CaseRunResult;\n\n constructor(result: import('./engine/types').CaseRunResult) {\n super(`Case \"${result.name}\" failed.`, {\n code: 'CASE_EXECUTION_FAILED',\n details: { caseId: result.caseId, runId: result.runId },\n });\n this.result = result;\n }\n}\n\nexport class WorkflowDocumentExecutionError extends WorkflowError {\n readonly result: import('./engine/types').WorkflowDocumentRunResult;\n\n constructor(result: import('./engine/types').WorkflowDocumentRunResult) {\n super(`Workflow document \"${result.sourcePath}\" failed.`, {\n code: 'WORKFLOW_DOCUMENT_EXECUTION_FAILED',\n details: {\n documentId: result.documentId,\n documentRunId: result.documentRunId,\n },\n });\n this.result = result;\n }\n}\n\nexport function normalizeNodeExecutionError(\n error: unknown,\n node: string,\n): WorkflowError {\n return error instanceof WorkflowError\n ? error\n : new NodeExecutionError(node, error);\n}\n","__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 { z } from 'zod/v4';\nimport { NodeDefinitionError } from '../errors';\nimport type {\n DefineNodeOptions,\n DefineNodeWithSchemaOptions,\n NodeDefinition,\n NodeDefinitionWithSchema,\n NodeInputSchema,\n} from './types';\n\nconst validateOptionalText = (\n value: unknown,\n field: 'title' | 'description',\n node: string,\n): void => {\n if (\n value !== undefined &&\n (typeof value !== 'string' || value.trim().length === 0)\n ) {\n throw new NodeDefinitionError(\n `Node \"${node}\" ${field} must be a non-empty string.`,\n { node, field },\n );\n }\n};\n\nconst validateInputSchema = (schema: unknown, node: string): void => {\n if (schema === undefined) return;\n if (!(schema instanceof z.ZodObject)) {\n throw new NodeDefinitionError(\n `Node \"${node}\" inputSchema must be a Zod object schema.`,\n { node, field: 'inputSchema' },\n );\n }\n if ('$' in schema.shape) {\n throw new NodeDefinitionError(\n `Node \"${node}\" inputSchema must not declare \"$\" as an input property.`,\n { node, field: 'inputSchema.$' },\n );\n }\n};\n\nconst validateDefinition = (options: {\n name: string;\n title?: unknown;\n description?: unknown;\n stringInputKey?: unknown;\n inputSchema?: unknown;\n execute: unknown;\n}): void => {\n if (!options || typeof options !== 'object') {\n throw new NodeDefinitionError('Node definition must be an object.');\n }\n\n if (typeof options.name !== 'string' || options.name.trim().length === 0) {\n throw new NodeDefinitionError('Node name must be a non-empty string.');\n }\n\n validateOptionalText(options.title, 'title', options.name);\n validateOptionalText(options.description, 'description', options.name);\n if (\n options.stringInputKey !== undefined &&\n options.stringInputKey !== false &&\n (typeof options.stringInputKey !== 'string' ||\n options.stringInputKey.trim().length === 0)\n ) {\n throw new NodeDefinitionError(\n `Node \"${options.name}\" stringInputKey must be a non-empty string or false.`,\n { node: options.name, field: 'stringInputKey' },\n );\n }\n validateInputSchema(options.inputSchema, options.name);\n\n if (\n typeof options.stringInputKey === 'string' &&\n options.inputSchema instanceof z.ZodObject &&\n !(options.stringInputKey in options.inputSchema.shape)\n ) {\n throw new NodeDefinitionError(\n `Node \"${options.name}\" stringInputKey must reference a field in inputSchema.`,\n { node: options.name, field: 'stringInputKey' },\n );\n }\n\n if (typeof options.execute !== 'function') {\n throw new NodeDefinitionError(\n `Node \"${options.name}\" must provide an execute function.`,\n { node: options.name },\n );\n }\n};\n\nexport function defineNode<\n TSchema extends NodeInputSchema,\n TData = unknown,\n TContext = unknown,\n>(\n options: DefineNodeWithSchemaOptions<TSchema, TData, TContext>,\n): NodeDefinitionWithSchema<TSchema, TData, TContext>;\n\nexport function defineNode<\n TInput = unknown,\n TData = unknown,\n TContext = unknown,\n>(\n options: DefineNodeOptions<TInput, TData, TContext>,\n): NodeDefinition<TInput, TData, TContext>;\n\nexport function defineNode(\n options: DefineNodeOptions<any, any, any>,\n): NodeDefinition<any, any, any> {\n validateDefinition(options);\n return options;\n}\n","import {\n type AgentTestRunnerNodeDefinition,\n type AgentTestRunnerNodeProvider,\n type CommonAgentTestRunnerApi,\n aiActInputSchema,\n aiActOptionsInputSchema,\n aiAssertInputSchema,\n aiAssertOptionsInputSchema,\n aiTapInputSchema,\n insightInputSchema,\n insightOptionsInputSchema,\n locateOptionsInputSchema,\n promptImageInputSchema,\n recordToReportInputSchema,\n recordToReportOptionsInputSchema,\n reportScreenshotInputSchema,\n structuredUserPromptInputSchema,\n userPromptInputSchema,\n} from '@midscene/core/agent/test-runner';\nimport { getDebug } from '@midscene/shared/logger';\nimport { z } from 'zod/v4';\nimport type { Awaitable } from '../engine/types';\nimport { NodeDefinitionError, NodeExecutionError } from '../errors';\nimport { defineNode } from '../node/define-node';\nimport type { NodeDefinition, NodeExecutionContext } from '../node/types';\n\nexport type MidsceneUIAgent = CommonAgentTestRunnerApi & {\n addDumpUpdateListener?(\n listener: (dump: string, execution?: MidsceneExecutionRef) => void,\n ): () => void;\n};\n\nexport {\n aiActInputSchema,\n aiActOptionsInputSchema,\n aiAssertInputSchema,\n aiAssertOptionsInputSchema,\n aiTapInputSchema,\n insightInputSchema,\n insightOptionsInputSchema,\n locateOptionsInputSchema,\n promptImageInputSchema,\n recordToReportInputSchema,\n recordToReportOptionsInputSchema,\n reportScreenshotInputSchema,\n structuredUserPromptInputSchema,\n userPromptInputSchema,\n};\n\nexport interface MidsceneExecutionRef {\n id?: string;\n}\n\nexport interface AgentProvider<TContext> {\n getAgent(\n runId: string,\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Awaitable<MidsceneUIAgent>;\n // biome-ignore lint/suspicious/noConfusingVoidType: providers without a report intentionally return void.\n releaseAgent?(runId: string): Awaitable<AgentReleaseResult | void>;\n dispose?(): Awaitable<void>;\n}\n\nexport interface AgentReleaseResult {\n /** Absolute path to the finalized report for this Agent scope. */\n reportPath?: string;\n}\n\nexport const waitInputSchema = z.strictObject({\n duration: z.number().positive().describe('How long to wait.'),\n unit: z\n .enum(['ms', 's', 'min'])\n .default('ms')\n .describe('Duration unit: milliseconds, seconds, or minutes.'),\n});\n\nexport type AiActNodeInput = z.infer<typeof aiActInputSchema>;\nexport type AiAssertNodeInput = z.infer<typeof aiAssertInputSchema>;\nexport type AiTapNodeInput = z.infer<typeof aiTapInputSchema>;\nexport type InsightNodeInput = z.infer<typeof insightInputSchema>;\nexport type RecordToReportNodeInput = z.infer<typeof recordToReportInputSchema>;\nexport type WaitNodeInput = z.infer<typeof waitInputSchema>;\n\nexport interface CreateMidsceneNodesOptions<TContext> {\n getAgent?(\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Awaitable<MidsceneUIAgent>;\n agentProvider?: AgentProvider<TContext>;\n /** Agent class that declares the Agent-backed Nodes to register. */\n agentClass: AgentTestRunnerNodeProvider;\n}\n\nconst waitFor = async (durationMs: number, signal: AbortSignal) => {\n if (signal.aborted) {\n throw signal.reason ?? new Error('Wait aborted.');\n }\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n signal.removeEventListener('abort', abort);\n resolve();\n }, durationMs);\n const abort = () => {\n clearTimeout(timeout);\n reject(signal.reason ?? new Error('Wait aborted.'));\n };\n signal.addEventListener('abort', abort, { once: true });\n });\n};\n\n/** Adapt Agent-owned descriptions to executable Midscene Test Nodes. */\nexport const createAgentTestRunnerNodes = <TContext>(\n definitions: readonly AgentTestRunnerNodeDefinition[],\n getAgent: (\n ctx: NodeExecutionContext<unknown, TContext>,\n ) => Awaitable<unknown>,\n): readonly NodeDefinition<any, any, TContext>[] => {\n const activeAgentCalls = new WeakMap<\n MidsceneUIAgent,\n { scopeId: string; node: string }\n >();\n const runAgentCall = async <T>(\n node: string,\n ctx: NodeExecutionContext<unknown, TContext>,\n agent: MidsceneUIAgent,\n call: () => Promise<T>,\n captureExecutions = true,\n ): Promise<T> => {\n const scopeId =\n ctx.scope === 'case' ? ctx.case.runId : ctx.document.documentRunId;\n const activeCall = activeAgentCalls.get(agent);\n if (activeCall) {\n throw new NodeExecutionError(\n node,\n new Error(\n `The same Agent instance cannot execute overlapping Midscene Test Steps. Active scope: ${activeCall.scopeId} (${activeCall.node}); requested scope: ${scopeId} (${node}).`,\n ),\n );\n }\n\n activeAgentCalls.set(agent, { scopeId, node });\n let removeListener: (() => void) | undefined;\n let sawExecutionWithoutId = false;\n const stopListening = () => {\n const remove = removeListener;\n removeListener = undefined;\n remove?.();\n };\n const stopListeningOnAbort = () => stopListening();\n try {\n if (captureExecutions && agent.addDumpUpdateListener) {\n removeListener = agent.addDumpUpdateListener((_dump, execution) => {\n if (!execution) return;\n if (!execution.id) {\n sawExecutionWithoutId = true;\n return;\n }\n ctx.report.addTrace({\n type: 'midscene-execution',\n executionId: execution.id,\n });\n });\n if (ctx.signal.aborted) stopListening();\n else {\n ctx.signal.addEventListener('abort', stopListeningOnAbort, {\n once: true,\n });\n }\n }\n return await call();\n } finally {\n ctx.signal.removeEventListener('abort', stopListeningOnAbort);\n try {\n stopListening();\n } finally {\n activeAgentCalls.delete(agent);\n }\n if (sawExecutionWithoutId) {\n warnReportTrace(\n `Skipped a report trace without a stable execution id for ${node} in scope ${scopeId}.`,\n );\n }\n }\n };\n\n return definitions.map((definition) =>\n defineNode({\n name: definition.name,\n ...(definition.title === undefined ? {} : { title: definition.title }),\n ...(definition.description === undefined\n ? {}\n : { description: definition.description }),\n ...(definition.stringInputKey === undefined\n ? {}\n : { stringInputKey: definition.stringInputKey }),\n inputSchema: definition.inputSchema,\n async execute(ctx) {\n const agent = await getAgent(ctx);\n const call = async () =>\n definition.execute(agent, ctx.input, { signal: ctx.signal });\n if (typeof agent !== 'object' || agent === null) return call();\n return runAgentCall(\n definition.name,\n ctx,\n agent as MidsceneUIAgent,\n call,\n );\n },\n }),\n );\n};\n\nconst warnReportTrace = getDebug('test-runner:report-trace', {\n console: true,\n});\n\nexport function createMidsceneNodes<TContext>(\n options: CreateMidsceneNodesOptions<TContext>,\n): readonly NodeDefinition<any, any, TContext>[] {\n if (!options || typeof options !== 'object') {\n throw new NodeDefinitionError(\n 'createMidsceneNodes() options must be an object.',\n );\n }\n if (\n typeof options.agentProvider?.getAgent !== 'function' &&\n typeof options.getAgent !== 'function'\n ) {\n throw new NodeDefinitionError(\n 'createMidsceneNodes() requires getAgent or agentProvider.getAgent.',\n );\n }\n if (\n !options.agentClass ||\n typeof options.agentClass.getTestRunnerNodeDefinitions !== 'function'\n ) {\n throw new NodeDefinitionError(\n 'createMidsceneNodes() requires agentClass.getTestRunnerNodeDefinitions().',\n );\n }\n\n const registeredAgentScopes = new Set<string>();\n const getExecutionId = (ctx: NodeExecutionContext<unknown, TContext>) =>\n ctx.scope === 'case' ? ctx.case.runId : ctx.document.documentRunId;\n const getAgent = async (\n ctx: NodeExecutionContext<unknown, TContext>,\n ): Promise<MidsceneUIAgent> => {\n if (!options.agentProvider) return options.getAgent!(ctx);\n const runId = getExecutionId(ctx);\n if (\n options.agentProvider.releaseAgent &&\n !registeredAgentScopes.has(runId)\n ) {\n registeredAgentScopes.add(runId);\n ctx.onTeardown(async () => {\n try {\n const released = await options.agentProvider!.releaseAgent!(runId);\n return released?.reportPath\n ? { reportPaths: [released.reportPath] }\n : undefined;\n } finally {\n registeredAgentScopes.delete(runId);\n }\n });\n }\n return options.agentProvider.getAgent(runId, ctx);\n };\n\n const agentDefinitions = options.agentClass.getTestRunnerNodeDefinitions();\n\n return [\n ...createAgentTestRunnerNodes(agentDefinitions, getAgent),\n defineNode<typeof waitInputSchema, unknown, TContext>({\n name: 'wait',\n description: 'Wait for a fixed duration while honoring cancellation.',\n stringInputKey: false,\n inputSchema: waitInputSchema,\n async execute(ctx) {\n const multiplier =\n ctx.input.unit === 'min'\n ? 60_000\n : ctx.input.unit === 's'\n ? 1_000\n : 1;\n const durationMs = ctx.input.duration * multiplier;\n await waitFor(durationMs, ctx.signal);\n return { summary: `Waited ${durationMs}ms` };\n },\n }),\n ];\n}\n"],"names":["WorkflowError","Error","undefined","message","options","NodeDefinitionError","details","NodeExecutionError","node","cause","causeMessage","String","__webpack_require__","definition","key","Object","obj","prop","Symbol","validateOptionalText","value","field","validateInputSchema","schema","z","validateDefinition","defineNode","waitInputSchema","waitFor","durationMs","signal","Promise","resolve","reject","timeout","setTimeout","abort","clearTimeout","createAgentTestRunnerNodes","definitions","getAgent","activeAgentCalls","WeakMap","runAgentCall","ctx","agent","call","captureExecutions","scopeId","activeCall","removeListener","sawExecutionWithoutId","stopListening","remove","stopListeningOnAbort","_dump","execution","warnReportTrace","getDebug","createMidsceneNodes","registeredAgentScopes","Set","getExecutionId","runId","released","agentDefinitions","multiplier"],"mappings":"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"}
|