@midscene/core 1.16.0 → 1.16.1

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.
Files changed (94) hide show
  1. package/dist/es/agent/agent-options.mjs +36 -0
  2. package/dist/es/agent/agent-options.mjs.map +1 -0
  3. package/dist/es/agent/agent-report-manager.mjs +323 -0
  4. package/dist/es/agent/agent-report-manager.mjs.map +1 -0
  5. package/dist/es/agent/agent.mjs +112 -228
  6. package/dist/es/agent/agent.mjs.map +1 -1
  7. package/dist/es/agent/cache-config.mjs +21 -1
  8. package/dist/es/agent/cache-config.mjs.map +1 -1
  9. package/dist/es/agent/tasks.mjs +3 -1
  10. package/dist/es/agent/tasks.mjs.map +1 -1
  11. package/dist/es/agent/utils.mjs +1 -1
  12. package/dist/es/report-generator.mjs +73 -33
  13. package/dist/es/report-generator.mjs.map +1 -1
  14. package/dist/es/report-html-template.mjs +1 -1
  15. package/dist/es/test-runner/engine/document-runtime.mjs +30 -24
  16. package/dist/es/test-runner/engine/document-runtime.mjs.map +1 -1
  17. package/dist/es/test-runner/engine/project-runtime.mjs +17 -11
  18. package/dist/es/test-runner/engine/project-runtime.mjs.map +1 -1
  19. package/dist/es/test-runner/engine/resource-operations.mjs +33 -8
  20. package/dist/es/test-runner/engine/resource-operations.mjs.map +1 -1
  21. package/dist/es/test-runner/engine/run-collected-case.mjs +1 -0
  22. package/dist/es/test-runner/engine/run-collected-case.mjs.map +1 -1
  23. package/dist/es/test-runner/engine/run-workflow-document.mjs +3 -0
  24. package/dist/es/test-runner/engine/run-workflow-document.mjs.map +1 -1
  25. package/dist/es/test-runner/engine/setup-timeout.mjs +37 -0
  26. package/dist/es/test-runner/engine/setup-timeout.mjs.map +1 -0
  27. package/dist/es/utils.mjs +1 -1
  28. package/dist/es/yaml/execution-session.mjs +2 -1
  29. package/dist/es/yaml/execution-session.mjs.map +1 -1
  30. package/dist/es/yaml/legacy-yaml-report.mjs +1 -1
  31. package/dist/es/yaml/legacy-yaml-report.mjs.map +1 -1
  32. package/dist/es/yaml/player.mjs +17 -3
  33. package/dist/es/yaml/player.mjs.map +1 -1
  34. package/dist/lib/agent/agent-options.js +73 -0
  35. package/dist/lib/agent/agent-options.js.map +1 -0
  36. package/dist/lib/agent/agent-report-manager.js +357 -0
  37. package/dist/lib/agent/agent-report-manager.js.map +1 -0
  38. package/dist/lib/agent/agent.js +110 -226
  39. package/dist/lib/agent/agent.js.map +1 -1
  40. package/dist/lib/agent/cache-config.js +23 -0
  41. package/dist/lib/agent/cache-config.js.map +1 -1
  42. package/dist/lib/agent/tasks.js +3 -1
  43. package/dist/lib/agent/tasks.js.map +1 -1
  44. package/dist/lib/agent/utils.js +1 -1
  45. package/dist/lib/report-generator.js +73 -33
  46. package/dist/lib/report-generator.js.map +1 -1
  47. package/dist/lib/report-html-template.js +1 -1
  48. package/dist/lib/test-runner/engine/document-runtime.js +30 -24
  49. package/dist/lib/test-runner/engine/document-runtime.js.map +1 -1
  50. package/dist/lib/test-runner/engine/project-runtime.js +17 -11
  51. package/dist/lib/test-runner/engine/project-runtime.js.map +1 -1
  52. package/dist/lib/test-runner/engine/resource-operations.js +36 -8
  53. package/dist/lib/test-runner/engine/resource-operations.js.map +1 -1
  54. package/dist/lib/test-runner/engine/run-collected-case.js +1 -0
  55. package/dist/lib/test-runner/engine/run-collected-case.js.map +1 -1
  56. package/dist/lib/test-runner/engine/run-workflow-document.js +3 -0
  57. package/dist/lib/test-runner/engine/run-workflow-document.js.map +1 -1
  58. package/dist/lib/test-runner/engine/setup-timeout.js +71 -0
  59. package/dist/lib/test-runner/engine/setup-timeout.js.map +1 -0
  60. package/dist/lib/utils.js +1 -1
  61. package/dist/lib/yaml/execution-session.js +4 -0
  62. package/dist/lib/yaml/execution-session.js.map +1 -1
  63. package/dist/lib/yaml/legacy-yaml-report.js +1 -1
  64. package/dist/lib/yaml/legacy-yaml-report.js.map +1 -1
  65. package/dist/lib/yaml/player.js +16 -2
  66. package/dist/lib/yaml/player.js.map +1 -1
  67. package/dist/types/agent/agent-options.d.ts +4 -0
  68. package/dist/types/agent/agent-options.d.ts.map +1 -0
  69. package/dist/types/agent/agent-report-manager.d.ts +92 -0
  70. package/dist/types/agent/agent-report-manager.d.ts.map +1 -0
  71. package/dist/types/agent/agent.d.ts +31 -24
  72. package/dist/types/agent/agent.d.ts.map +1 -1
  73. package/dist/types/agent/cache-config.d.ts +10 -0
  74. package/dist/types/agent/cache-config.d.ts.map +1 -1
  75. package/dist/types/agent/tasks.d.ts +1 -0
  76. package/dist/types/agent/tasks.d.ts.map +1 -1
  77. package/dist/types/report-generator.d.ts +5 -1
  78. package/dist/types/report-generator.d.ts.map +1 -1
  79. package/dist/types/test-runner/engine/document-runtime.d.ts.map +1 -1
  80. package/dist/types/test-runner/engine/project-runtime.d.ts.map +1 -1
  81. package/dist/types/test-runner/engine/resource-operations.d.ts +5 -0
  82. package/dist/types/test-runner/engine/resource-operations.d.ts.map +1 -1
  83. package/dist/types/test-runner/engine/run-collected-case.d.ts.map +1 -1
  84. package/dist/types/test-runner/engine/run-workflow-document.d.ts.map +1 -1
  85. package/dist/types/test-runner/engine/setup-timeout.d.ts +3 -0
  86. package/dist/types/test-runner/engine/setup-timeout.d.ts.map +1 -0
  87. package/dist/types/test-runner/engine/types.d.ts +7 -0
  88. package/dist/types/test-runner/engine/types.d.ts.map +1 -1
  89. package/dist/types/test-runner/project.d.ts +22 -0
  90. package/dist/types/test-runner/project.d.ts.map +1 -1
  91. package/dist/types/yaml/execution-session.d.ts +2 -0
  92. package/dist/types/yaml/execution-session.d.ts.map +1 -1
  93. package/dist/types/yaml/player.d.ts.map +1 -1
  94. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"test-runner/engine/resource-operations.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/test-runner/engine/resource-operations.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 { getDebug } from '@midscene/shared/logger';\nimport { uuid } from '@midscene/shared/utils';\nimport type {\n TestRunReportCleanup,\n TestRunReportOperationEvent,\n TestRunReportOperationReference,\n} from '../../test-run-report';\nimport { WorkflowError } from '../errors';\nimport { sanitizeReportError } from '../reporting/sanitize';\n\ninterface OperationIdentity {\n scopeId: string;\n stepId?: string;\n node?: string;\n}\ninterface ResourceOperation {\n signal: AbortSignal;\n operationId: string;\n identity?: OperationIdentity;\n settled?: boolean;\n blockers?: Set<ResourceOperation>;\n}\ntype OperationListener = (event: Readonly<TestRunReportOperationEvent>) => void;\n\ninterface CleanupOwner {\n resources: Set<object>;\n signal?: AbortSignal;\n blockers: Set<ResourceOperation>;\n}\n\ninterface ResourceScope {\n operations: Map<object, number>;\n resources?: Set<object>;\n cleanupOwner?: CleanupOwner;\n}\n\ninterface ResourceHandle {\n operations: Map<Promise<unknown>, ResourceOperation>;\n retiring: Set<CleanupOwner>;\n cleanup?: Promise<unknown>;\n cleanupState?: {\n operationId?: string;\n status: 'pending' | 'completed' | 'failed';\n blockers: Set<ResourceOperation>;\n error?: unknown;\n };\n}\n\ninterface ResourceState {\n resources: WeakMap<object, ResourceHandle>;\n scopes: WeakMap<AbortSignal, ResourceScope>;\n parents: WeakMap<AbortSignal, AbortSignal>;\n cleanupOwners: WeakMap<AbortSignal, CleanupOwner>;\n identities: WeakMap<AbortSignal, OperationIdentity>;\n listeners: WeakMap<AbortSignal, Set<OperationListener>>;\n}\n\n// CJS and ESM hosts must agree about ownership of the same Agent instance.\nconst admissionErrorKey = Symbol.for('@midscene/core/resource-admission-error');\nconst stateKey = Symbol.for('@midscene/core/resource-operations/v4');\nconst host = globalThis as typeof globalThis & { [stateKey]?: ResourceState };\nhost[stateKey] ??= {\n resources: new WeakMap(),\n scopes: new WeakMap(),\n parents: new WeakMap(),\n cleanupOwners: new WeakMap(),\n identities: new WeakMap(),\n listeners: new WeakMap(),\n};\nconst { resources, scopes, parents, cleanupOwners, identities, listeners } =\n host[stateKey];\nconst resourceHandle = (resource: object): ResourceHandle => {\n let handle = resources.get(resource);\n if (!handle) {\n handle = {\n operations: new Map(),\n retiring: new Set(),\n };\n resources.set(resource, handle);\n }\n return handle;\n};\n\n/** Actual teardown completion belongs to the owner, never to a thrown error. */\nexport const getResourceCleanupCompletion = (\n owner: object,\n): Promise<unknown> | undefined => resources.get(owner)?.cleanup;\n\nfunction blockingReferences(\n blockers: Iterable<ResourceOperation>,\n): TestRunReportOperationReference[] {\n const references = new Map<string, TestRunReportOperationReference>();\n const visited = new Set<ResourceOperation>();\n const visit = (record: ResourceOperation) => {\n if (visited.has(record)) return;\n visited.add(record);\n if (!record.settled)\n references.set(record.operationId, {\n operationId: record.operationId,\n ...record.identity,\n });\n for (const blocker of record.blockers ?? []) visit(blocker);\n };\n for (const blocker of blockers) visit(blocker);\n return [...references.values()];\n}\n\n/** Read a copy at the publication boundary; never expose the live cleanup state. */\nexport function getResourceCleanupSnapshot(\n owner: object,\n): TestRunReportCleanup {\n const state = resources.get(owner)?.cleanupState;\n return freezeEvent({\n capturedAt: new Date().toISOString(),\n status: state?.status ?? 'not-required',\n ...(state?.operationId ? { operationId: state.operationId } : {}),\n ...(state?.status === 'pending'\n ? { blockingOperations: blockingReferences(state.blockers) }\n : {}),\n ...(state?.error === undefined\n ? {}\n : { error: sanitizeReportError(state.error) }),\n });\n}\n\nexport const RESOURCE_CLEANUP_GRACE_MS = 1000;\nexport const RESOURCE_RECOVERY_GRACE_MS = 30_000;\nconst RESOURCE_TEARDOWN_GRACE_MS = 10_000;\n\nexport function getPendingScopeOperations(\n signal: AbortSignal,\n): TestRunReportOperationReference[] {\n return freezeEvent(\n blockingReferences(\n [...(scopes.get(signal)?.operations.keys() ?? [])].flatMap((resource) => [\n ...(resources.get(resource)?.operations.values() ?? []),\n ]),\n ),\n );\n}\n\n/** Snapshotting must not wait for a timed-out operation to release its resource. */\nexport const hasPendingResourceOperation = (resource: object): boolean =>\n (resources.get(resource)?.operations.size ?? 0) > 0;\n\n/** Resource ancestry is independent of cancellation: cleanup can outlive abort. */\nexport function linkResourceSignal(signal: AbortSignal, parent?: AbortSignal) {\n if (parent && parent !== signal) parents.set(signal, parent);\n}\n\nfunction* ownerSignals(signal?: AbortSignal): Generator<AbortSignal> {\n const seen = new Set<AbortSignal>();\n for (\n let owner = signal;\n owner && !seen.has(owner);\n owner = parents.get(owner)\n ) {\n seen.add(owner);\n yield owner;\n }\n}\n\n/** Each Case/document owns its cleanup, even when cancellation is shared. */\nexport function createResourceScope(parent?: AbortSignal) {\n const controller = new AbortController();\n const scope: ResourceScope = { operations: new Map(), resources: new Set() };\n scopes.set(controller.signal, scope);\n linkResourceSignal(controller.signal, parent);\n const abort = () => controller.abort(parent?.reason);\n if (parent?.aborted) abort();\n else parent?.addEventListener('abort', abort, { once: true });\n return {\n signal: controller.signal,\n dispose() {\n parent?.removeEventListener('abort', abort);\n scope.resources = undefined;\n if (!scope.operations.size) scopes.delete(controller.signal);\n },\n };\n}\n\nexport function assertResourceAvailable(\n resource: object,\n exclusive = false,\n signal?: AbortSignal,\n): boolean {\n const retiringOwners = resources.get(resource)?.retiring;\n const isOwnerCleanup = [...ownerSignals(signal)].some((ownerSignal) => {\n const owner = cleanupOwners.get(ownerSignal);\n return owner !== undefined && retiringOwners?.has(owner);\n });\n if (retiringOwners?.size && !isOwnerCleanup)\n throw new WorkflowError(\n 'A resource cannot execute overlapping Runner operations while its cleanup is pending.',\n { code: 'RESOURCE_CLEANUP_PENDING' },\n );\n const pending = resources.get(resource)?.operations;\n if (exclusive && pending?.size)\n throw new WorkflowError(\n 'The same Agent instance cannot execute overlapping Runner operations.',\n { code: 'RESOURCE_OPERATION_PENDING' },\n );\n if (\n pending &&\n [...pending.values()].some((operation) => operation.signal.aborted)\n )\n throw new WorkflowError(\n 'Cannot reuse an Agent while an aborted YAML action or Runner operation is still running.',\n { code: 'RESOURCE_OPERATION_PENDING' },\n );\n return isOwnerCleanup;\n}\n\n/** Capture subscribers at registration: late settlement stays with its original run. */\nexport function observeResourceOperations(\n signal: AbortSignal,\n listener: OperationListener,\n) {\n const subscribers = listeners.get(signal) ?? new Set<OperationListener>();\n listeners.set(signal, subscribers);\n subscribers.add(listener);\n return () => {\n subscribers.delete(listener);\n if (!subscribers.size) listeners.delete(signal);\n };\n}\n\nexport function setResourceOperationIdentity(\n signal: AbortSignal,\n identity: OperationIdentity,\n) {\n identities.set(signal, Object.freeze({ ...identity }));\n}\n\nfunction freezeEvent<T>(value: T): T {\n if (typeof value === 'object' && value !== null && !Object.isFrozen(value)) {\n for (const child of Object.values(value)) freezeEvent(child);\n Object.freeze(value);\n }\n return value;\n}\n\nexport function recordOperation(\n operation: Promise<unknown>,\n signal: AbortSignal,\n operationKind: TestRunReportOperationEvent['operationKind'],\n) {\n const owners = [...ownerSignals(signal)];\n const identity = owners.map((owner) => identities.get(owner)).find(Boolean);\n const record: ResourceOperation = { signal, operationId: uuid(), identity };\n const subscribers = new Set(\n owners.flatMap((owner) => [...(listeners.get(owner) ?? [])]),\n );\n let settled = false;\n const emit = (\n event: Omit<\n TestRunReportOperationEvent,\n 'operationId' | 'operationKind' | 'at'\n >,\n ) => {\n const frozen = freezeEvent({\n ...identity,\n operationId: record.operationId,\n operationKind,\n at: new Date().toISOString(),\n ...event,\n });\n for (const subscriber of subscribers) {\n try {\n subscriber(frozen);\n } catch (error) {\n getDebug('runner:operations', { console: true })(\n `Operation observer failed: ${String(error)}`,\n );\n }\n }\n };\n const abort = () =>\n emit({\n kind: 'cancel-requested',\n error: sanitizeReportError(signal.reason),\n });\n emit({ kind: 'started' });\n if (signal.aborted) abort();\n else signal.addEventListener('abort', abort, { once: true });\n const finish = (\n status: 'success' | 'failed' | 'not-run',\n error?: unknown,\n ) => {\n settled = true;\n record.settled = true;\n signal.removeEventListener('abort', abort);\n emit({\n kind: 'settled',\n status,\n ...(status !== 'success' ? { error: sanitizeReportError(error) } : {}),\n });\n };\n void operation.then(\n () => finish('success'),\n (error) =>\n finish(isResourceAdmissionError(error) ? 'not-run' : 'failed', error),\n );\n return {\n record,\n runnerReturned(status: 'success' | 'failed' | 'not-run') {\n emit({ kind: 'runner-returned', status, pending: !settled });\n },\n cleanupDeferred(blockers: Iterable<ResourceOperation>) {\n emit({\n kind: 'cleanup-deferred',\n blockingOperations: blockingReferences(blockers),\n });\n },\n };\n}\n\n/** A scheduling decision, distinct from an action that ran and failed. */\nexport class ResourceAdmissionError extends WorkflowError {\n readonly blockedBy?: string;\n readonly [admissionErrorKey] = true;\n constructor(code: string, blockers: readonly ResourceOperation[]) {\n super(\n 'The Agent is occupied by an unfinished operation or pending cleanup; this action was not started.',\n {\n code,\n details: {\n blockingOperations: blockers.map(({ operationId, identity }) => ({\n operationId,\n ...identity,\n })),\n },\n },\n );\n this.blockedBy = blockers.find(\n (blocker) => blocker.identity?.stepId,\n )?.identity?.stepId;\n }\n}\n\nexport function isResourceAdmissionError(\n error: unknown,\n): error is ResourceAdmissionError {\n return (\n typeof error === 'object' &&\n error !== null &&\n (error as ResourceAdmissionError)[admissionErrorKey] === true\n );\n}\n\nexport function admitResourceOperation(\n resource: object,\n signal: AbortSignal,\n exclusive = true,\n): boolean {\n let isCleanupOwner: boolean;\n try {\n isCleanupOwner = assertResourceAvailable(resource, exclusive, signal);\n } catch (error) {\n if (\n error instanceof WorkflowError &&\n ['RESOURCE_OPERATION_PENDING', 'RESOURCE_CLEANUP_PENDING'].includes(\n error.code,\n )\n )\n throw new ResourceAdmissionError(error.code, [\n ...(resources.get(resource)?.operations.values() ?? []),\n ...[...(resources.get(resource)?.retiring ?? [])].flatMap((owner) => [\n ...owner.blockers,\n ]),\n ]);\n throw error;\n }\n return isCleanupOwner;\n}\n\nconst retainForCleanup = (owner: CleanupOwner, resource: object) => {\n owner.resources.add(resource);\n const handle = resourceHandle(resource);\n for (const operation of handle.operations.values())\n owner.blockers.add(operation);\n handle.retiring.add(owner);\n};\n\n/** Acquisition establishes cleanup ownership even if action admission is rejected. */\nexport function retainResourceForScope(resource: object, signal: AbortSignal) {\n let retained = false;\n for (const ownerSignal of ownerSignals(signal)) {\n const scope = scopes.get(ownerSignal);\n if (!retained && scope?.resources) {\n scope.resources.add(resource);\n retained = true;\n }\n if (scope?.cleanupOwner) retainForCleanup(scope.cleanupOwner, resource);\n }\n}\n\n/** Track actual completion, not the Runner timeout race. */\nexport function trackResourceOperation<T>(\n resource: object,\n operation: Promise<T>,\n signal: AbortSignal,\n kind: TestRunReportOperationEvent['operationKind'] = 'resource',\n existingObservation?: ReturnType<typeof recordOperation>,\n): Promise<T> {\n const observation =\n existingObservation ?? recordOperation(operation, signal, kind);\n const active = resourceHandle(resource).operations;\n active.set(operation, observation.record);\n const ownerScopes: Array<[AbortSignal, ResourceScope]> = [];\n let retainedByScope = false;\n for (const ownerSignal of ownerSignals(signal)) {\n const scope: ResourceScope = scopes.get(ownerSignal) ?? {\n operations: new Map(),\n };\n scopes.set(ownerSignal, scope);\n scope.operations.set(resource, (scope.operations.get(resource) ?? 0) + 1);\n ownerScopes.push([ownerSignal, scope]);\n // Only the closest owner retains idle resources for its teardown. Parents\n // wait on active operations, not every Agent used by completed Cases.\n if (!retainedByScope && scope.resources) {\n scope.resources.add(resource);\n retainedByScope = true;\n }\n const cleanupOwner = cleanupOwners.get(ownerSignal);\n if (cleanupOwner) {\n cleanupOwner.blockers.add(observation.record);\n retainForCleanup(cleanupOwner, resource);\n }\n }\n const finish = () => {\n active.delete(operation);\n for (const [ownerSignal, scope] of ownerScopes) {\n const count = scope.operations.get(resource)! - 1;\n if (count) scope.operations.set(resource, count);\n else scope.operations.delete(resource);\n if (!scope.operations.size && !scope.resources)\n scopes.delete(ownerSignal);\n }\n };\n void operation.then(finish, finish);\n return operation;\n}\n\nexport async function waitForResourceIdle(resource: object): Promise<void> {\n while (resources.get(resource)?.operations?.size)\n await Promise.allSettled([...resources.get(resource)!.operations.keys()]);\n}\n\n/** Wait for this scope's cancelled work before scheduling its next Step. */\nexport async function recoverCancelledScopeResources(\n signal: AbortSignal,\n graceMs = RESOURCE_RECOVERY_GRACE_MS,\n): Promise<number> {\n signal.throwIfAborted();\n const startedAt = Date.now();\n const pendingOperations = () => {\n const pending: Array<{\n operation: Promise<unknown>;\n signal: AbortSignal;\n resource: object;\n record: ResourceOperation;\n }> = [];\n for (const resource of scopes.get(signal)?.operations.keys() ?? []) {\n for (const [operation, tracked] of resources.get(resource)?.operations ??\n []) {\n const ownerSignal = tracked.signal;\n if (\n ownerSignal.aborted &&\n [...ownerSignals(ownerSignal)].includes(signal)\n )\n pending.push({\n operation,\n signal: ownerSignal,\n resource,\n record: tracked,\n });\n }\n }\n return pending;\n };\n let pending = pendingOperations();\n if (!pending.length) return 0;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let onAbort!: () => void;\n const stopped = new Promise<never>((_resolve, reject) => {\n onAbort = () => reject(signal.reason);\n signal.addEventListener('abort', onAbort, { once: true });\n timer = setTimeout(() => {\n const blockingOperations = blockingReferences(\n pending.map(({ record }) => record),\n );\n const blockedByStepId = blockingOperations.every(\n ({ stepId }) => stepId === blockingOperations[0]?.stepId,\n )\n ? blockingOperations[0]?.stepId\n : undefined;\n reject(\n new WorkflowError(\n `The previous operation was still running after ${graceMs / 1000} s. Later steps were not started.`,\n {\n code: 'RESOURCE_RECOVERY_TIMEOUT',\n details: {\n graceMs,\n waitedMs: Date.now() - startedAt,\n resourceCount: new Set(pending.map(({ resource }) => resource))\n .size,\n blockingOperations,\n blockedByStepId,\n },\n cause: pending[0]?.signal.reason,\n },\n ),\n );\n }, graceMs);\n });\n try {\n while (pending.length) {\n await Promise.race([\n Promise.allSettled(pending.map(({ operation }) => operation)),\n stopped,\n ]);\n signal.throwIfAborted();\n pending = pendingOperations();\n }\n return Date.now() - startedAt;\n } finally {\n clearTimeout(timer);\n signal.removeEventListener('abort', onAbort);\n }\n}\n\nexport class ResourceCleanupDeferredError extends WorkflowError {\n constructor(\n graceMs: number,\n resourceCount: number,\n blockers: readonly ResourceOperation[] = [],\n ) {\n super(\n `Resource cleanup did not finish within ${graceMs}ms. Resources remain quarantined until cleanup settles.`,\n {\n code: 'RESOURCE_CLEANUP_DEFERRED',\n details: {\n graceMs,\n resourceCount,\n blockingOperations: blockers.map(({ operationId, identity }) => ({\n operationId,\n ...identity,\n })),\n },\n },\n );\n }\n}\n\ninterface CleanupOptions {\n /** Stable owner of this cleanup, distinct from borrowed resource identities. */\n owner?: object;\n /** Parent scope observes deferred completion without host-specific forwarding. */\n signal?: AbortSignal;\n graceMs?: number;\n onDeferredError(error: unknown): void;\n}\n\n/** Bound waiting, but keep ownership until the actual cleanup has finished. */\nasync function runResourceCleanup<T>(\n resources: readonly object[],\n cleanup: () => Promise<T>,\n options: CleanupOptions,\n beforeCleanup?: {\n signal: AbortSignal;\n run(signal: AbortSignal): Promise<void>;\n },\n): Promise<T> {\n const owner: CleanupOwner = {\n resources: new Set(),\n blockers: new Set(),\n signal: beforeCleanup?.signal,\n };\n for (const resource of resources) retainForCleanup(owner, resource);\n if (owner.signal) cleanupOwners.set(owner.signal, owner);\n const ownerScope = options.signal ? scopes.get(options.signal) : undefined;\n if (ownerScope) ownerScope.cleanupOwner = owner;\n\n let defer!: () => void;\n const deferred = new Promise<{ deferred: true }>((resolve) => {\n defer = () => resolve({ deferred: true });\n });\n let graceMs = options.graceMs ?? RESOURCE_CLEANUP_GRACE_MS;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const drain = async () => {\n timer = setTimeout(defer, graceMs);\n try {\n // An acquisition may finish late and add another shared resource to its\n // owner. Keep draining that resource before calling any disposer.\n while (true) {\n const pending = [...owner.resources].filter(\n (resource) => resourceHandle(resource).operations.size,\n );\n if (!pending.length) return;\n await Promise.all(pending.map(waitForResourceIdle));\n }\n } finally {\n clearTimeout(timer);\n }\n };\n const completion = (async () => {\n try {\n if (beforeCleanup) {\n // Hooks may use idle resources owned by this cleanup. Busy resources\n // still reject overlapping actions, including cleanup actions.\n await beforeCleanup.run(beforeCleanup.signal);\n }\n // Lifecycle hooks can themselves time out with an action still running.\n // Drain both the original work and any operation started by the hook\n // before disposing the resource.\n await drain();\n graceMs = options.graceMs ?? RESOURCE_TEARDOWN_GRACE_MS;\n timer = setTimeout(defer, graceMs);\n return await cleanup();\n } finally {\n clearTimeout(timer);\n if (owner.signal) cleanupOwners.delete(owner.signal);\n if (ownerScope?.cleanupOwner === owner)\n ownerScope.cleanupOwner = undefined;\n for (const resource of owner.resources) {\n const owners = resourceHandle(resource).retiring;\n owners.delete(owner);\n }\n }\n })();\n const cleanupObservation = options.signal\n ? recordOperation(completion, options.signal, 'cleanup')\n : undefined;\n const ownerKey = options.owner ?? beforeCleanup?.signal ?? resources[0];\n const cleanupState: NonNullable<ResourceHandle['cleanupState']> = {\n status: 'pending',\n operationId: cleanupObservation?.record.operationId,\n blockers: owner.blockers,\n };\n if (cleanupObservation) cleanupObservation.record.blockers = owner.blockers;\n if (ownerKey) {\n resourceHandle(ownerKey).cleanup = completion;\n resourceHandle(ownerKey).cleanupState = cleanupState;\n }\n void completion.then(\n () => {\n cleanupState.status = 'completed';\n },\n (error) => {\n cleanupState.status = 'failed';\n cleanupState.error = error;\n },\n );\n const outcome = await Promise.race([\n completion.then((value) => ({ value })),\n deferred,\n ]);\n if ('deferred' in outcome) {\n cleanupObservation?.cleanupDeferred(owner.blockers);\n void completion.catch((error) => {\n try {\n options.onDeferredError(error);\n } catch {\n // The returned completion still carries the original cleanup failure.\n }\n });\n if (options.signal)\n trackResourceOperation(\n {},\n completion,\n options.signal,\n 'cleanup',\n cleanupObservation,\n );\n throw new ResourceCleanupDeferredError(graceMs, owner.resources.size, [\n ...owner.blockers,\n ]);\n }\n return outcome.value;\n}\n\nexport function cleanupResources<T>(\n resources: readonly object[],\n cleanup: () => Promise<T>,\n options: CleanupOptions,\n): Promise<T> {\n return runResourceCleanup(resources, cleanup, options);\n}\n\nexport async function cleanupScopeResources<T>(\n signal: AbortSignal,\n cleanup: () => Promise<T>,\n options: CleanupOptions & {\n beforeCleanup?(signal: AbortSignal): Promise<void>;\n },\n): Promise<T> {\n const cleanupSignal = new AbortController().signal;\n linkResourceSignal(cleanupSignal, signal);\n const scope = scopes.get(signal);\n return runResourceCleanup(\n [...(scope?.resources ?? []), ...(scope?.operations.keys() ?? [])],\n cleanup,\n { ...options, owner: signal, signal },\n options.beforeCleanup\n ? { signal: cleanupSignal, run: options.beforeCleanup }\n : undefined,\n );\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","admissionErrorKey","stateKey","host","globalThis","WeakMap","resources","scopes","parents","cleanupOwners","identities","listeners","resourceHandle","resource","handle","Map","Set","getResourceCleanupCompletion","owner","blockingReferences","blockers","references","visited","visit","record","blocker","getResourceCleanupSnapshot","state","freezeEvent","Date","undefined","sanitizeReportError","RESOURCE_CLEANUP_GRACE_MS","RESOURCE_RECOVERY_GRACE_MS","RESOURCE_TEARDOWN_GRACE_MS","getPendingScopeOperations","signal","hasPendingResourceOperation","linkResourceSignal","parent","ownerSignals","seen","createResourceScope","controller","AbortController","scope","abort","assertResourceAvailable","exclusive","retiringOwners","isOwnerCleanup","ownerSignal","WorkflowError","pending","operation","observeResourceOperations","listener","subscribers","setResourceOperationIdentity","identity","value","child","recordOperation","operationKind","owners","Boolean","uuid","settled","emit","event","frozen","subscriber","error","getDebug","String","finish","status","isResourceAdmissionError","_admissionErrorKey","ResourceAdmissionError","code","operationId","admitResourceOperation","isCleanupOwner","retainForCleanup","retainResourceForScope","retained","trackResourceOperation","kind","existingObservation","observation","active","ownerScopes","retainedByScope","cleanupOwner","count","waitForResourceIdle","Promise","recoverCancelledScopeResources","graceMs","startedAt","pendingOperations","tracked","timer","onAbort","stopped","_resolve","reject","setTimeout","blockingOperations","blockedByStepId","stepId","clearTimeout","ResourceCleanupDeferredError","resourceCount","runResourceCleanup","cleanup","options","beforeCleanup","ownerScope","defer","deferred","resolve","drain","completion","cleanupObservation","ownerKey","cleanupState","outcome","cleanupResources","cleanupScopeResources","cleanupSignal"],"mappings":"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"}
1
+ {"version":3,"file":"test-runner/engine/resource-operations.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/test-runner/engine/resource-operations.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 { getDebug } from '@midscene/shared/logger';\nimport { uuid } from '@midscene/shared/utils';\nimport type {\n TestRunReportCleanup,\n TestRunReportOperationEvent,\n TestRunReportOperationReference,\n} from '../../test-run-report';\nimport { WorkflowError } from '../errors';\nimport { sanitizeReportError } from '../reporting/sanitize';\n\ninterface OperationIdentity {\n scopeId: string;\n stepId?: string;\n node?: string;\n}\ninterface ResourceOperation {\n signal: AbortSignal;\n operationId: string;\n identity?: OperationIdentity;\n settled?: boolean;\n blockers?: Set<ResourceOperation>;\n}\ntype OperationListener = (event: Readonly<TestRunReportOperationEvent>) => void;\n\ninterface CleanupOwner {\n resources: Set<object>;\n signal?: AbortSignal;\n blockers: Set<ResourceOperation>;\n}\n\ninterface ResourceScope {\n operations: Map<object, number>;\n resources?: Set<object>;\n cleanupOwner?: CleanupOwner;\n}\n\ninterface ResourceHandle {\n operations: Map<Promise<unknown>, ResourceOperation>;\n retiring: Set<CleanupOwner>;\n cleanup?: Promise<unknown>;\n cleanupState?: {\n operationId?: string;\n status: 'pending' | 'completed' | 'failed';\n blockers: Set<ResourceOperation>;\n error?: unknown;\n };\n}\n\ninterface ResourceState {\n resources: WeakMap<object, ResourceHandle>;\n scopes: WeakMap<AbortSignal, ResourceScope>;\n parents: WeakMap<AbortSignal, AbortSignal>;\n cleanupOwners: WeakMap<AbortSignal, CleanupOwner>;\n identities: WeakMap<AbortSignal, OperationIdentity>;\n listeners: WeakMap<AbortSignal, Set<OperationListener>>;\n}\n\n// CJS and ESM hosts must agree about ownership of the same Agent instance.\nconst admissionErrorKey = Symbol.for('@midscene/core/resource-admission-error');\nconst stateKey = Symbol.for('@midscene/core/resource-operations/v4');\nconst host = globalThis as typeof globalThis & { [stateKey]?: ResourceState };\nhost[stateKey] ??= {\n resources: new WeakMap(),\n scopes: new WeakMap(),\n parents: new WeakMap(),\n cleanupOwners: new WeakMap(),\n identities: new WeakMap(),\n listeners: new WeakMap(),\n};\nconst { resources, scopes, parents, cleanupOwners, identities, listeners } =\n host[stateKey];\nconst resourceHandle = (resource: object): ResourceHandle => {\n let handle = resources.get(resource);\n if (!handle) {\n handle = {\n operations: new Map(),\n retiring: new Set(),\n };\n resources.set(resource, handle);\n }\n return handle;\n};\n\n/** Actual teardown completion belongs to the owner, never to a thrown error. */\nexport const getResourceCleanupCompletion = (\n owner: object,\n): Promise<unknown> | undefined => resources.get(owner)?.cleanup;\n\nfunction blockingReferences(\n blockers: Iterable<ResourceOperation>,\n): TestRunReportOperationReference[] {\n const references = new Map<string, TestRunReportOperationReference>();\n const visited = new Set<ResourceOperation>();\n const visit = (record: ResourceOperation) => {\n if (visited.has(record)) return;\n visited.add(record);\n if (!record.settled)\n references.set(record.operationId, {\n operationId: record.operationId,\n ...record.identity,\n });\n for (const blocker of record.blockers ?? []) visit(blocker);\n };\n for (const blocker of blockers) visit(blocker);\n return [...references.values()];\n}\n\n/** Read a copy at the publication boundary; never expose the live cleanup state. */\nexport function getResourceCleanupSnapshot(\n owner: object,\n): TestRunReportCleanup {\n const state = resources.get(owner)?.cleanupState;\n return freezeEvent({\n capturedAt: new Date().toISOString(),\n status: state?.status ?? 'not-required',\n ...(state?.operationId ? { operationId: state.operationId } : {}),\n ...(state?.status === 'pending'\n ? { blockingOperations: blockingReferences(state.blockers) }\n : {}),\n ...(state?.error === undefined\n ? {}\n : { error: sanitizeReportError(state.error) }),\n });\n}\n\nexport const RESOURCE_CLEANUP_GRACE_MS = 1000;\nexport const RESOURCE_RECOVERY_GRACE_MS = 30_000;\nconst RESOURCE_TEARDOWN_GRACE_MS = 10_000;\n\nexport function getPendingScopeOperations(\n signal: AbortSignal,\n): TestRunReportOperationReference[] {\n return freezeEvent(\n blockingReferences(\n [...(scopes.get(signal)?.operations.keys() ?? [])].flatMap((resource) => [\n ...(resources.get(resource)?.operations.values() ?? []),\n ]),\n ),\n );\n}\n\n/** Snapshotting must not wait for a timed-out operation to release its resource. */\nexport const hasPendingResourceOperation = (resource: object): boolean =>\n (resources.get(resource)?.operations.size ?? 0) > 0;\n\n/** Resource ancestry is independent of cancellation: cleanup can outlive abort. */\nexport function linkResourceSignal(signal: AbortSignal, parent?: AbortSignal) {\n if (parent && parent !== signal) parents.set(signal, parent);\n}\n\nfunction* ownerSignals(signal?: AbortSignal): Generator<AbortSignal> {\n const seen = new Set<AbortSignal>();\n for (\n let owner = signal;\n owner && !seen.has(owner);\n owner = parents.get(owner)\n ) {\n seen.add(owner);\n yield owner;\n }\n}\n\n/** Each Case/document owns its cleanup, even when cancellation is shared. */\nexport function createResourceScope(parent?: AbortSignal) {\n const controller = new AbortController();\n const scope: ResourceScope = { operations: new Map(), resources: new Set() };\n scopes.set(controller.signal, scope);\n linkResourceSignal(controller.signal, parent);\n const abort = () => controller.abort(parent?.reason);\n if (parent?.aborted) abort();\n else parent?.addEventListener('abort', abort, { once: true });\n return {\n signal: controller.signal,\n abort(reason?: unknown) {\n controller.abort(reason);\n },\n dispose() {\n parent?.removeEventListener('abort', abort);\n scope.resources = undefined;\n if (!scope.operations.size) scopes.delete(controller.signal);\n },\n };\n}\n\nexport function assertResourceAvailable(\n resource: object,\n exclusive = false,\n signal?: AbortSignal,\n): boolean {\n const retiringOwners = resources.get(resource)?.retiring;\n const isOwnerCleanup = [...ownerSignals(signal)].some((ownerSignal) => {\n const owner = cleanupOwners.get(ownerSignal);\n return owner !== undefined && retiringOwners?.has(owner);\n });\n if (retiringOwners?.size && !isOwnerCleanup)\n throw new WorkflowError(\n 'A resource cannot execute overlapping Runner operations while its cleanup is pending.',\n { code: 'RESOURCE_CLEANUP_PENDING' },\n );\n const pending = resources.get(resource)?.operations;\n if (exclusive && pending?.size)\n throw new WorkflowError(\n 'The same Agent instance cannot execute overlapping Runner operations.',\n { code: 'RESOURCE_OPERATION_PENDING' },\n );\n if (\n pending &&\n [...pending.values()].some((operation) => operation.signal.aborted)\n )\n throw new WorkflowError(\n 'Cannot reuse an Agent while an aborted YAML action or Runner operation is still running.',\n { code: 'RESOURCE_OPERATION_PENDING' },\n );\n return isOwnerCleanup;\n}\n\n/** Capture subscribers at registration: late settlement stays with its original run. */\nexport function observeResourceOperations(\n signal: AbortSignal,\n listener: OperationListener,\n) {\n const subscribers = listeners.get(signal) ?? new Set<OperationListener>();\n listeners.set(signal, subscribers);\n subscribers.add(listener);\n return () => {\n subscribers.delete(listener);\n if (!subscribers.size) listeners.delete(signal);\n };\n}\n\nexport function setResourceOperationIdentity(\n signal: AbortSignal,\n identity: OperationIdentity,\n) {\n identities.set(signal, Object.freeze({ ...identity }));\n}\n\nfunction freezeEvent<T>(value: T): T {\n if (typeof value === 'object' && value !== null && !Object.isFrozen(value)) {\n for (const child of Object.values(value)) freezeEvent(child);\n Object.freeze(value);\n }\n return value;\n}\n\nexport function recordOperation(\n operation: Promise<unknown>,\n signal: AbortSignal,\n operationKind: TestRunReportOperationEvent['operationKind'],\n) {\n const owners = [...ownerSignals(signal)];\n const identity = owners.map((owner) => identities.get(owner)).find(Boolean);\n const record: ResourceOperation = { signal, operationId: uuid(), identity };\n const subscribers = new Set(\n owners.flatMap((owner) => [...(listeners.get(owner) ?? [])]),\n );\n let settled = false;\n const emit = (\n event: Omit<\n TestRunReportOperationEvent,\n 'operationId' | 'operationKind' | 'at'\n >,\n ) => {\n const frozen = freezeEvent({\n ...identity,\n operationId: record.operationId,\n operationKind,\n at: new Date().toISOString(),\n ...event,\n });\n for (const subscriber of subscribers) {\n try {\n subscriber(frozen);\n } catch (error) {\n getDebug('runner:operations', { console: true })(\n `Operation observer failed: ${String(error)}`,\n );\n }\n }\n };\n const abort = () =>\n emit({\n kind: 'cancel-requested',\n error: sanitizeReportError(signal.reason),\n });\n emit({ kind: 'started' });\n if (signal.aborted) abort();\n else signal.addEventListener('abort', abort, { once: true });\n const finish = (\n status: 'success' | 'failed' | 'not-run',\n error?: unknown,\n ) => {\n settled = true;\n record.settled = true;\n signal.removeEventListener('abort', abort);\n emit({\n kind: 'settled',\n status,\n ...(status !== 'success' ? { error: sanitizeReportError(error) } : {}),\n });\n };\n void operation.then(\n () => finish('success'),\n (error) =>\n finish(isResourceAdmissionError(error) ? 'not-run' : 'failed', error),\n );\n return {\n record,\n runnerReturned(status: 'success' | 'failed' | 'not-run') {\n emit({ kind: 'runner-returned', status, pending: !settled });\n },\n cleanupDeferred(blockers: Iterable<ResourceOperation>) {\n emit({\n kind: 'cleanup-deferred',\n blockingOperations: blockingReferences(blockers),\n });\n },\n };\n}\n\n/** A scheduling decision, distinct from an action that ran and failed. */\nexport class ResourceAdmissionError extends WorkflowError {\n readonly blockedBy?: string;\n readonly [admissionErrorKey] = true;\n constructor(code: string, blockers: readonly ResourceOperation[]) {\n super(\n 'The Agent is occupied by an unfinished operation or pending cleanup; this action was not started.',\n {\n code,\n details: {\n blockingOperations: blockers.map(({ operationId, identity }) => ({\n operationId,\n ...identity,\n })),\n },\n },\n );\n this.blockedBy = blockers.find(\n (blocker) => blocker.identity?.stepId,\n )?.identity?.stepId;\n }\n}\n\nexport function isResourceAdmissionError(\n error: unknown,\n): error is ResourceAdmissionError {\n return (\n typeof error === 'object' &&\n error !== null &&\n (error as ResourceAdmissionError)[admissionErrorKey] === true\n );\n}\n\nexport function admitResourceOperation(\n resource: object,\n signal: AbortSignal,\n exclusive = true,\n): boolean {\n let isCleanupOwner: boolean;\n try {\n isCleanupOwner = assertResourceAvailable(resource, exclusive, signal);\n } catch (error) {\n if (\n error instanceof WorkflowError &&\n ['RESOURCE_OPERATION_PENDING', 'RESOURCE_CLEANUP_PENDING'].includes(\n error.code,\n )\n )\n throw new ResourceAdmissionError(error.code, [\n ...(resources.get(resource)?.operations.values() ?? []),\n ...[...(resources.get(resource)?.retiring ?? [])].flatMap((owner) => [\n ...owner.blockers,\n ]),\n ]);\n throw error;\n }\n return isCleanupOwner;\n}\n\nconst retainForCleanup = (owner: CleanupOwner, resource: object) => {\n owner.resources.add(resource);\n const handle = resourceHandle(resource);\n for (const operation of handle.operations.values())\n owner.blockers.add(operation);\n handle.retiring.add(owner);\n};\n\n/** Acquisition establishes cleanup ownership even if action admission is rejected. */\nexport function retainResourceForScope(resource: object, signal: AbortSignal) {\n let retained = false;\n for (const ownerSignal of ownerSignals(signal)) {\n const scope = scopes.get(ownerSignal);\n if (!retained && scope?.resources) {\n scope.resources.add(resource);\n retained = true;\n }\n if (scope?.cleanupOwner) retainForCleanup(scope.cleanupOwner, resource);\n }\n}\n\n/** Track actual completion, not the Runner timeout race. */\nexport function trackResourceOperation<T>(\n resource: object,\n operation: Promise<T>,\n signal: AbortSignal,\n kind: TestRunReportOperationEvent['operationKind'] = 'resource',\n existingObservation?: ReturnType<typeof recordOperation>,\n): Promise<T> {\n const observation =\n existingObservation ?? recordOperation(operation, signal, kind);\n const active = resourceHandle(resource).operations;\n active.set(operation, observation.record);\n const ownerScopes: Array<[AbortSignal, ResourceScope]> = [];\n let retainedByScope = false;\n for (const ownerSignal of ownerSignals(signal)) {\n const scope: ResourceScope = scopes.get(ownerSignal) ?? {\n operations: new Map(),\n };\n scopes.set(ownerSignal, scope);\n scope.operations.set(resource, (scope.operations.get(resource) ?? 0) + 1);\n ownerScopes.push([ownerSignal, scope]);\n // Only the closest owner retains idle resources for its teardown. Parents\n // wait on active operations, not every Agent used by completed Cases.\n if (!retainedByScope && scope.resources) {\n scope.resources.add(resource);\n retainedByScope = true;\n }\n const cleanupOwner = cleanupOwners.get(ownerSignal);\n if (cleanupOwner) {\n cleanupOwner.blockers.add(observation.record);\n retainForCleanup(cleanupOwner, resource);\n }\n }\n const finish = () => {\n active.delete(operation);\n for (const [ownerSignal, scope] of ownerScopes) {\n const count = scope.operations.get(resource)! - 1;\n if (count) scope.operations.set(resource, count);\n else scope.operations.delete(resource);\n if (!scope.operations.size && !scope.resources)\n scopes.delete(ownerSignal);\n }\n };\n void operation.then(finish, finish);\n return operation;\n}\n\nexport async function waitForResourceIdle(resource: object): Promise<void> {\n while (resources.get(resource)?.operations?.size)\n await Promise.allSettled([...resources.get(resource)!.operations.keys()]);\n}\n\n/** Wait for actual descendant settlement, including deferred cleanup. */\nexport async function waitForScopeOperations(\n signal: AbortSignal,\n): Promise<void> {\n while (true) {\n const active = [...(scopes.get(signal)?.operations.keys() ?? [])];\n if (!active.length) return;\n await Promise.all(active.map(waitForResourceIdle));\n }\n}\n\n/** Wait for this scope's cancelled work before scheduling its next Step. */\nexport async function recoverCancelledScopeResources(\n signal: AbortSignal,\n graceMs = RESOURCE_RECOVERY_GRACE_MS,\n): Promise<number> {\n signal.throwIfAborted();\n const startedAt = Date.now();\n const pendingOperations = () => {\n const pending: Array<{\n operation: Promise<unknown>;\n signal: AbortSignal;\n resource: object;\n record: ResourceOperation;\n }> = [];\n for (const resource of scopes.get(signal)?.operations.keys() ?? []) {\n for (const [operation, tracked] of resources.get(resource)?.operations ??\n []) {\n const ownerSignal = tracked.signal;\n if (\n ownerSignal.aborted &&\n [...ownerSignals(ownerSignal)].includes(signal)\n )\n pending.push({\n operation,\n signal: ownerSignal,\n resource,\n record: tracked,\n });\n }\n }\n return pending;\n };\n let pending = pendingOperations();\n if (!pending.length) return 0;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let onAbort!: () => void;\n const stopped = new Promise<never>((_resolve, reject) => {\n onAbort = () => reject(signal.reason);\n signal.addEventListener('abort', onAbort, { once: true });\n timer = setTimeout(() => {\n const blockingOperations = blockingReferences(\n pending.map(({ record }) => record),\n );\n const blockedByStepId = blockingOperations.every(\n ({ stepId }) => stepId === blockingOperations[0]?.stepId,\n )\n ? blockingOperations[0]?.stepId\n : undefined;\n reject(\n new WorkflowError(\n `The previous operation was still running after ${graceMs / 1000} s. Later steps were not started.`,\n {\n code: 'RESOURCE_RECOVERY_TIMEOUT',\n details: {\n graceMs,\n waitedMs: Date.now() - startedAt,\n resourceCount: new Set(pending.map(({ resource }) => resource))\n .size,\n blockingOperations,\n blockedByStepId,\n },\n cause: pending[0]?.signal.reason,\n },\n ),\n );\n }, graceMs);\n });\n try {\n while (pending.length) {\n await Promise.race([\n Promise.allSettled(pending.map(({ operation }) => operation)),\n stopped,\n ]);\n signal.throwIfAborted();\n pending = pendingOperations();\n }\n return Date.now() - startedAt;\n } finally {\n clearTimeout(timer);\n signal.removeEventListener('abort', onAbort);\n }\n}\n\nexport class ResourceCleanupDeferredError extends WorkflowError {\n constructor(\n graceMs: number,\n resourceCount: number,\n blockers: readonly ResourceOperation[] = [],\n ) {\n super(\n `Resource cleanup did not finish within ${graceMs}ms. Resources remain quarantined until cleanup settles.`,\n {\n code: 'RESOURCE_CLEANUP_DEFERRED',\n details: {\n graceMs,\n resourceCount,\n blockingOperations: blockers.map(({ operationId, identity }) => ({\n operationId,\n ...identity,\n })),\n },\n },\n );\n }\n}\n\ninterface CleanupOptions {\n /** Stable owner of this cleanup, distinct from borrowed resource identities. */\n owner?: object;\n /** Parent scope observes deferred completion without host-specific forwarding. */\n signal?: AbortSignal;\n graceMs?: number;\n /** Optional total deadline, including hooks, draining and all disposers. */\n totalTimeoutMs?: number;\n onDeferredError(error: unknown): void;\n}\n\n/** Bound waiting, but keep ownership until the actual cleanup has finished. */\nasync function runResourceCleanup<T>(\n resources: readonly object[],\n cleanup: () => Promise<T>,\n options: CleanupOptions,\n beforeCleanup?: {\n signal: AbortSignal;\n abort(reason: unknown): void;\n run(signal: AbortSignal): Promise<void>;\n },\n): Promise<T> {\n const owner: CleanupOwner = {\n resources: new Set(),\n blockers: new Set(),\n signal: beforeCleanup?.signal,\n };\n for (const resource of resources) retainForCleanup(owner, resource);\n if (owner.signal) cleanupOwners.set(owner.signal, owner);\n const ownerScope = options.signal ? scopes.get(options.signal) : undefined;\n if (ownerScope) ownerScope.cleanupOwner = owner;\n\n let defer!: () => void;\n const deferred = new Promise<{ deferred: true }>((resolve) => {\n defer = () => {\n if (options.totalTimeoutMs !== undefined)\n beforeCleanup?.abort(\n new WorkflowError(\n `Resource cleanup timed out after ${options.totalTimeoutMs}ms.`,\n {\n code: 'TEARDOWN_TIMEOUT',\n details: { timeoutMs: options.totalTimeoutMs },\n },\n ),\n );\n resolve({ deferred: true });\n };\n });\n let graceMs =\n options.totalTimeoutMs ?? options.graceMs ?? RESOURCE_CLEANUP_GRACE_MS;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const drain = async () => {\n if (options.totalTimeoutMs === undefined)\n timer = setTimeout(defer, graceMs);\n try {\n // An acquisition may finish late and add another shared resource to its\n // owner. Keep draining that resource before calling any disposer.\n while (true) {\n const pending = [...owner.resources].filter(\n (resource) => resourceHandle(resource).operations.size,\n );\n if (!pending.length) return;\n await Promise.all(pending.map(waitForResourceIdle));\n }\n } finally {\n if (options.totalTimeoutMs === undefined) clearTimeout(timer);\n }\n };\n const completion = (async () => {\n if (options.totalTimeoutMs !== undefined)\n timer = setTimeout(defer, Math.max(0, options.totalTimeoutMs));\n try {\n if (beforeCleanup) {\n // Hooks may use idle resources owned by this cleanup. Busy resources\n // still reject overlapping actions, including cleanup actions.\n await beforeCleanup.run(beforeCleanup.signal);\n }\n // Lifecycle hooks can themselves time out with an action still running.\n // Drain both the original work and any operation started by the hook\n // before disposing the resource.\n await drain();\n if (options.totalTimeoutMs === undefined) {\n graceMs = options.graceMs ?? RESOURCE_TEARDOWN_GRACE_MS;\n timer = setTimeout(defer, graceMs);\n }\n return await cleanup();\n } finally {\n clearTimeout(timer);\n if (owner.signal) cleanupOwners.delete(owner.signal);\n if (ownerScope?.cleanupOwner === owner)\n ownerScope.cleanupOwner = undefined;\n for (const resource of owner.resources) {\n const owners = resourceHandle(resource).retiring;\n owners.delete(owner);\n }\n }\n })();\n const cleanupObservation = options.signal\n ? recordOperation(completion, options.signal, 'cleanup')\n : undefined;\n const ownerKey = options.owner ?? beforeCleanup?.signal ?? resources[0];\n const cleanupState: NonNullable<ResourceHandle['cleanupState']> = {\n status: 'pending',\n operationId: cleanupObservation?.record.operationId,\n blockers: owner.blockers,\n };\n if (cleanupObservation) cleanupObservation.record.blockers = owner.blockers;\n if (ownerKey) {\n resourceHandle(ownerKey).cleanup = completion;\n resourceHandle(ownerKey).cleanupState = cleanupState;\n }\n void completion.then(\n () => {\n cleanupState.status = 'completed';\n },\n (error) => {\n cleanupState.status = 'failed';\n cleanupState.error = error;\n },\n );\n const outcome = await Promise.race([\n completion.then((value) => ({ value })),\n deferred,\n ]);\n if ('deferred' in outcome) {\n cleanupObservation?.cleanupDeferred(owner.blockers);\n void completion.catch((error) => {\n try {\n options.onDeferredError(error);\n } catch {\n // The returned completion still carries the original cleanup failure.\n }\n });\n if (options.signal)\n trackResourceOperation(\n {},\n completion,\n options.signal,\n 'cleanup',\n cleanupObservation,\n );\n throw new ResourceCleanupDeferredError(graceMs, owner.resources.size, [\n ...owner.blockers,\n ]);\n }\n return outcome.value;\n}\n\nexport function cleanupResources<T>(\n resources: readonly object[],\n cleanup: () => Promise<T>,\n options: CleanupOptions,\n): Promise<T> {\n return runResourceCleanup(resources, cleanup, options);\n}\n\nexport async function cleanupScopeResources<T>(\n signal: AbortSignal,\n cleanup: () => Promise<T>,\n options: CleanupOptions & {\n beforeCleanup?(signal: AbortSignal): Promise<void>;\n },\n): Promise<T> {\n const cleanupController = new AbortController();\n const cleanupSignal = cleanupController.signal;\n linkResourceSignal(cleanupSignal, signal);\n const scope = scopes.get(signal);\n return runResourceCleanup(\n [...(scope?.resources ?? []), ...(scope?.operations.keys() ?? [])],\n cleanup,\n { ...options, owner: signal, signal },\n options.beforeCleanup\n ? {\n signal: cleanupSignal,\n abort: (reason) => cleanupController.abort(reason),\n run: options.beforeCleanup,\n }\n : undefined,\n );\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","admissionErrorKey","stateKey","host","globalThis","WeakMap","resources","scopes","parents","cleanupOwners","identities","listeners","resourceHandle","resource","handle","Map","Set","getResourceCleanupCompletion","owner","blockingReferences","blockers","references","visited","visit","record","blocker","getResourceCleanupSnapshot","state","freezeEvent","Date","undefined","sanitizeReportError","RESOURCE_CLEANUP_GRACE_MS","RESOURCE_RECOVERY_GRACE_MS","RESOURCE_TEARDOWN_GRACE_MS","getPendingScopeOperations","signal","hasPendingResourceOperation","linkResourceSignal","parent","ownerSignals","seen","createResourceScope","controller","AbortController","scope","abort","reason","assertResourceAvailable","exclusive","retiringOwners","isOwnerCleanup","ownerSignal","WorkflowError","pending","operation","observeResourceOperations","listener","subscribers","setResourceOperationIdentity","identity","value","child","recordOperation","operationKind","owners","Boolean","uuid","settled","emit","event","frozen","subscriber","error","getDebug","String","finish","status","isResourceAdmissionError","_admissionErrorKey","ResourceAdmissionError","code","operationId","admitResourceOperation","isCleanupOwner","retainForCleanup","retainResourceForScope","retained","trackResourceOperation","kind","existingObservation","observation","active","ownerScopes","retainedByScope","cleanupOwner","count","waitForResourceIdle","Promise","waitForScopeOperations","recoverCancelledScopeResources","graceMs","startedAt","pendingOperations","tracked","timer","onAbort","stopped","_resolve","reject","setTimeout","blockingOperations","blockedByStepId","stepId","clearTimeout","ResourceCleanupDeferredError","resourceCount","runResourceCleanup","cleanup","options","beforeCleanup","ownerScope","defer","deferred","resolve","drain","completion","Math","cleanupObservation","ownerKey","cleanupState","outcome","cleanupResources","cleanupScopeResources","cleanupController","cleanupSignal"],"mappings":"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"}
@@ -146,6 +146,7 @@ async function runCollectedCase(collectedCase, options) {
146
146
  };
147
147
  try {
148
148
  if (phases.afterEach.length || teardownStack.length) await (0, external_resource_operations_js_namespaceObject.cleanupScopeResources)(scopeSignal, cleanup, {
149
+ totalTimeoutMs: options.teardownTimeoutMs?.(),
149
150
  beforeCleanup: async (cleanupSignal)=>{
150
151
  try {
151
152
  await runPhase('afterEach', afterEach, cleanupSignal);
@@ -1 +1 @@
1
- {"version":3,"file":"test-runner/engine/run-collected-case.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/test-runner/engine/run-collected-case.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 { getDebug } from '@midscene/shared/logger';\nimport { uuid as randomUUID } from '@midscene/shared/utils';\nimport { NodeScopeTeardownError, WorkflowLifecycleError } from '../errors';\nimport type { CollectedCase, NormalizedStep } from '../parser/types';\nimport { executeStep } from './execute-step';\nimport {\n WorkflowExecutionFailure,\n asExecutionError,\n} from './execution-failure';\nimport {\n ResourceCleanupDeferredError,\n cleanupScopeResources,\n createResourceScope,\n getPendingScopeOperations,\n getResourceCleanupSnapshot,\n recoverCancelledScopeResources,\n setResourceOperationIdentity,\n} from './resource-operations';\nimport { phaseResult } from './result-metadata';\nimport { reportPathsFromTeardown } from './scope-teardown';\nimport type {\n CaseNodePhase,\n CaseRunResult,\n NodeCaseContext,\n NodeScopeTeardown,\n RunCollectedCaseOptions,\n StepRunResult,\n} from './types';\n\nexport async function runCollectedCase<TContext = undefined>(\n collectedCase: CollectedCase,\n options: RunCollectedCaseOptions<TContext>,\n): Promise<CaseRunResult> {\n const phases: Record<CaseNodePhase, readonly NormalizedStep[]> = {\n beforeEach: options.beforeEach ?? [],\n steps: collectedCase.definition.steps,\n afterEach: options.afterEach ?? [],\n };\n const nodes = {\n beforeEach: phases.beforeEach.map((step) => options.resolveNode(step.node)),\n steps: phases.steps.map((step) => options.resolveNode(step.node)),\n afterEach: phases.afterEach.map((step) => options.resolveNode(step.node)),\n };\n const resourceScope = createResourceScope(options.signal);\n const scopeSignal = resourceScope.signal;\n const runId = options.createRunId?.() ?? randomUUID();\n const startedAt = new Date();\n setResourceOperationIdentity(scopeSignal, { scopeId: runId });\n const beforeEach: StepRunResult[] = [];\n const steps: StepRunResult[] = [];\n const afterEach: StepRunResult[] = [];\n const capturedSources = new Map<\n string,\n import('./types').WorkflowReportSource\n >();\n const teardownStack: Array<{\n registrationIndex: number;\n node: string;\n teardown: NodeScopeTeardown;\n }> = [];\n let acceptingTeardowns = true;\n\n const onTeardown = (node: string, teardown: NodeScopeTeardown): void => {\n if (!acceptingTeardowns) {\n throw new WorkflowLifecycleError(\n 'Node teardown can only be registered while a case attempt is running.',\n { runId, node },\n );\n }\n if (typeof teardown !== 'function') {\n throw new WorkflowLifecycleError(\n 'Node onTeardown() requires a teardown function.',\n { runId, node },\n );\n }\n teardownStack.push({\n registrationIndex: teardownStack.length,\n node,\n teardown,\n });\n };\n\n const runPhase = async (\n phase: CaseNodePhase,\n results: StepRunResult[],\n signal = scopeSignal,\n ): Promise<void> => {\n for (const [stepIndex, step] of phases[phase].entries()) {\n // A Step timeout ends the Runner's wait, not the underlying operation.\n // Recovery belongs between Steps, outside the next Step's timeout budget.\n const waitForPreviousOperationMs =\n stepIndex > 0 ? await recoverCancelledScopeResources(signal) : 0;\n const caseContext: NodeCaseContext = {\n caseId: collectedCase.caseId,\n runId,\n projectName: options.projectName ?? collectedCase.projectId,\n attemptIndex: options.attemptIndex ?? 0,\n name: collectedCase.definition.name,\n sourcePath: collectedCase.sourcePath,\n caseIndex: collectedCase.caseIndex,\n phase,\n stepIndex,\n };\n const stepInfo = {\n scope: 'case' as const,\n node: step.node,\n stepCount: phases[phase].length,\n case: caseContext,\n };\n await options.onStepStart?.(stepInfo);\n const result = await executeStep(\n step,\n nodes[phase][stepIndex],\n { scope: 'case', case: caseContext },\n options.context as TContext,\n {\n signal,\n defaultTimeoutMs: options.defaultTimeoutMs,\n onTeardown,\n },\n );\n if (waitForPreviousOperationMs > 0)\n result.waitForPreviousOperationMs = waitForPreviousOperationMs;\n results.push(result);\n for (const source of result.report?.sources ?? [])\n capturedSources.set(\n `${source.sourcePath}\\u0000${source.dumpPath ?? ''}`,\n source,\n );\n await options.onStepResult?.(stepInfo, result);\n if (result.status !== 'success' && !result.continuedAfterError) break;\n }\n };\n\n const executionErrors: unknown[] = [];\n try {\n await runPhase('beforeEach', beforeEach);\n if (!beforeEach.some((step) => step.status !== 'success')) {\n await runPhase('steps', steps);\n }\n } catch (error) {\n executionErrors.push(error);\n }\n const teardownErrors: NodeScopeTeardownError[] = [];\n const reportPaths = new Set<string>();\n const reportSources: import('./types').WorkflowReportSource[] = [];\n const cleanupExecutionErrors: unknown[] = [];\n let deferredCleanup = false;\n const cleanup = async () => {\n const priorTeardownErrors = teardownErrors.length;\n acceptingTeardowns = false;\n for (const {\n registrationIndex,\n node,\n teardown,\n } of teardownStack.reverse()) {\n try {\n const released = await teardown();\n reportSources.push(...(released?.reportSources ?? []));\n for (const path of reportPathsFromTeardown(released)) {\n reportPaths.add(path);\n }\n } catch (error) {\n teardownErrors.push(\n new NodeScopeTeardownError(error, {\n scope: 'case',\n scopeId: runId,\n node,\n registrationIndex,\n }),\n );\n }\n }\n {\n const errors = [\n ...cleanupExecutionErrors,\n ...teardownErrors.slice(priorTeardownErrors),\n ];\n if (errors.length)\n throw new AggregateError(errors, 'Case cleanup failed');\n }\n };\n try {\n if (phases.afterEach.length || teardownStack.length)\n await cleanupScopeResources(scopeSignal, cleanup, {\n beforeCleanup: async (cleanupSignal) => {\n try {\n await runPhase('afterEach', afterEach, cleanupSignal);\n } catch (error) {\n executionErrors.push(error);\n cleanupExecutionErrors.push(error);\n }\n },\n onDeferredError: (error) =>\n getDebug('runner:cleanup', { console: true })(\n `Deferred Case cleanup failed: ${String(error)}`,\n ),\n });\n else acceptingTeardowns = false;\n } catch (error) {\n deferredCleanup = error instanceof ResourceCleanupDeferredError;\n if (!deferredCleanup) acceptingTeardowns = false;\n if (\n !deferredCleanup &&\n !teardownErrors.length &&\n !cleanupExecutionErrors.length\n )\n teardownErrors.push(\n new NodeScopeTeardownError(error, {\n scope: 'case',\n scopeId: runId,\n node: 'resource-drain',\n registrationIndex: -1,\n }),\n );\n }\n const endedAt = new Date();\n const cleanupSnapshot = getResourceCleanupSnapshot(scopeSignal);\n const pendingOperations = getPendingScopeOperations(scopeSignal);\n const phaseResults = {\n beforeEach: phaseResult(phases.beforeEach.length, beforeEach),\n steps: phaseResult(phases.steps.length, steps),\n afterEach: phaseResult(phases.afterEach.length, afterEach),\n };\n const result: CaseRunResult = {\n caseId: collectedCase.caseId,\n runId,\n projectName: options.projectName ?? collectedCase.projectId,\n attemptIndex: options.attemptIndex ?? 0,\n name: collectedCase.definition.name,\n sourcePath: collectedCase.sourcePath,\n caseIndex: collectedCase.caseIndex,\n status:\n executionErrors.length > 0 ||\n beforeEach.some((step) => step.status !== 'success') ||\n steps.some((step) => step.status !== 'success') ||\n afterEach.some((step) => step.status !== 'success') ||\n cleanupSnapshot.status === 'pending' ||\n cleanupSnapshot.status === 'failed' ||\n pendingOperations.length > 0 ||\n teardownErrors.length > 0\n ? 'failed'\n : 'success',\n beforeEach: [...beforeEach],\n steps: [...steps],\n afterEach: [...afterEach],\n executionStatus: Object.values(phaseResults).some(\n (phase) => phase.status === 'failed',\n )\n ? 'failed'\n : Object.values(phaseResults).some((phase) => phase.status === 'not-run')\n ? 'not-run'\n : 'success',\n phases: phaseResults,\n cleanup: cleanupSnapshot,\n ...(pendingOperations.length ? { pendingOperations } : {}),\n ...(executionErrors.length\n ? { executionErrors: executionErrors.map(asExecutionError) }\n : {}),\n ...(teardownErrors.length > 0\n ? { teardownErrors: [...teardownErrors] }\n : {}),\n ...(reportPaths.size > 0 ? { reportPaths: [...reportPaths] } : {}),\n ...(capturedSources.size || reportSources.length\n ? { reportSources: [...capturedSources.values(), ...reportSources] }\n : {}),\n ...(options.reportScopeId ? { reportScopeId: options.reportScopeId } : {}),\n startedAt: startedAt.toISOString(),\n endedAt: endedAt.toISOString(),\n durationMs: Math.max(0, endedAt.getTime() - startedAt.getTime()),\n };\n\n try {\n await options.onResult?.(result);\n } catch (error) {\n executionErrors.push(error);\n result.status = 'failed';\n result.executionErrors = executionErrors.map(asExecutionError);\n }\n resourceScope.dispose();\n if (executionErrors.length)\n throw new WorkflowExecutionFailure(result, executionErrors);\n return result;\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","runCollectedCase","collectedCase","options","phases","nodes","step","resourceScope","createResourceScope","scopeSignal","runId","randomUUID","startedAt","Date","setResourceOperationIdentity","beforeEach","steps","afterEach","capturedSources","Map","teardownStack","acceptingTeardowns","onTeardown","node","teardown","WorkflowLifecycleError","runPhase","phase","results","signal","stepIndex","waitForPreviousOperationMs","recoverCancelledScopeResources","caseContext","stepInfo","result","executeStep","source","executionErrors","error","teardownErrors","reportPaths","Set","reportSources","cleanupExecutionErrors","deferredCleanup","cleanup","priorTeardownErrors","registrationIndex","released","path","reportPathsFromTeardown","NodeScopeTeardownError","errors","AggregateError","cleanupScopeResources","cleanupSignal","getDebug","String","ResourceCleanupDeferredError","endedAt","cleanupSnapshot","getResourceCleanupSnapshot","pendingOperations","getPendingScopeOperations","phaseResults","phaseResult","asExecutionError","Math","WorkflowExecutionFailure"],"mappings":"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"}
1
+ {"version":3,"file":"test-runner/engine/run-collected-case.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/test-runner/engine/run-collected-case.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 { getDebug } from '@midscene/shared/logger';\nimport { uuid as randomUUID } from '@midscene/shared/utils';\nimport { NodeScopeTeardownError, WorkflowLifecycleError } from '../errors';\nimport type { CollectedCase, NormalizedStep } from '../parser/types';\nimport { executeStep } from './execute-step';\nimport {\n WorkflowExecutionFailure,\n asExecutionError,\n} from './execution-failure';\nimport {\n ResourceCleanupDeferredError,\n cleanupScopeResources,\n createResourceScope,\n getPendingScopeOperations,\n getResourceCleanupSnapshot,\n recoverCancelledScopeResources,\n setResourceOperationIdentity,\n} from './resource-operations';\nimport { phaseResult } from './result-metadata';\nimport { reportPathsFromTeardown } from './scope-teardown';\nimport type {\n CaseNodePhase,\n CaseRunResult,\n NodeCaseContext,\n NodeScopeTeardown,\n RunCollectedCaseOptions,\n StepRunResult,\n} from './types';\n\nexport async function runCollectedCase<TContext = undefined>(\n collectedCase: CollectedCase,\n options: RunCollectedCaseOptions<TContext>,\n): Promise<CaseRunResult> {\n const phases: Record<CaseNodePhase, readonly NormalizedStep[]> = {\n beforeEach: options.beforeEach ?? [],\n steps: collectedCase.definition.steps,\n afterEach: options.afterEach ?? [],\n };\n const nodes = {\n beforeEach: phases.beforeEach.map((step) => options.resolveNode(step.node)),\n steps: phases.steps.map((step) => options.resolveNode(step.node)),\n afterEach: phases.afterEach.map((step) => options.resolveNode(step.node)),\n };\n const resourceScope = createResourceScope(options.signal);\n const scopeSignal = resourceScope.signal;\n const runId = options.createRunId?.() ?? randomUUID();\n const startedAt = new Date();\n setResourceOperationIdentity(scopeSignal, { scopeId: runId });\n const beforeEach: StepRunResult[] = [];\n const steps: StepRunResult[] = [];\n const afterEach: StepRunResult[] = [];\n const capturedSources = new Map<\n string,\n import('./types').WorkflowReportSource\n >();\n const teardownStack: Array<{\n registrationIndex: number;\n node: string;\n teardown: NodeScopeTeardown;\n }> = [];\n let acceptingTeardowns = true;\n\n const onTeardown = (node: string, teardown: NodeScopeTeardown): void => {\n if (!acceptingTeardowns) {\n throw new WorkflowLifecycleError(\n 'Node teardown can only be registered while a case attempt is running.',\n { runId, node },\n );\n }\n if (typeof teardown !== 'function') {\n throw new WorkflowLifecycleError(\n 'Node onTeardown() requires a teardown function.',\n { runId, node },\n );\n }\n teardownStack.push({\n registrationIndex: teardownStack.length,\n node,\n teardown,\n });\n };\n\n const runPhase = async (\n phase: CaseNodePhase,\n results: StepRunResult[],\n signal = scopeSignal,\n ): Promise<void> => {\n for (const [stepIndex, step] of phases[phase].entries()) {\n // A Step timeout ends the Runner's wait, not the underlying operation.\n // Recovery belongs between Steps, outside the next Step's timeout budget.\n const waitForPreviousOperationMs =\n stepIndex > 0 ? await recoverCancelledScopeResources(signal) : 0;\n const caseContext: NodeCaseContext = {\n caseId: collectedCase.caseId,\n runId,\n projectName: options.projectName ?? collectedCase.projectId,\n attemptIndex: options.attemptIndex ?? 0,\n name: collectedCase.definition.name,\n sourcePath: collectedCase.sourcePath,\n caseIndex: collectedCase.caseIndex,\n phase,\n stepIndex,\n };\n const stepInfo = {\n scope: 'case' as const,\n node: step.node,\n stepCount: phases[phase].length,\n case: caseContext,\n };\n await options.onStepStart?.(stepInfo);\n const result = await executeStep(\n step,\n nodes[phase][stepIndex],\n { scope: 'case', case: caseContext },\n options.context as TContext,\n {\n signal,\n defaultTimeoutMs: options.defaultTimeoutMs,\n onTeardown,\n },\n );\n if (waitForPreviousOperationMs > 0)\n result.waitForPreviousOperationMs = waitForPreviousOperationMs;\n results.push(result);\n for (const source of result.report?.sources ?? [])\n capturedSources.set(\n `${source.sourcePath}\\u0000${source.dumpPath ?? ''}`,\n source,\n );\n await options.onStepResult?.(stepInfo, result);\n if (result.status !== 'success' && !result.continuedAfterError) break;\n }\n };\n\n const executionErrors: unknown[] = [];\n try {\n await runPhase('beforeEach', beforeEach);\n if (!beforeEach.some((step) => step.status !== 'success')) {\n await runPhase('steps', steps);\n }\n } catch (error) {\n executionErrors.push(error);\n }\n const teardownErrors: NodeScopeTeardownError[] = [];\n const reportPaths = new Set<string>();\n const reportSources: import('./types').WorkflowReportSource[] = [];\n const cleanupExecutionErrors: unknown[] = [];\n let deferredCleanup = false;\n const cleanup = async () => {\n const priorTeardownErrors = teardownErrors.length;\n acceptingTeardowns = false;\n for (const {\n registrationIndex,\n node,\n teardown,\n } of teardownStack.reverse()) {\n try {\n const released = await teardown();\n reportSources.push(...(released?.reportSources ?? []));\n for (const path of reportPathsFromTeardown(released)) {\n reportPaths.add(path);\n }\n } catch (error) {\n teardownErrors.push(\n new NodeScopeTeardownError(error, {\n scope: 'case',\n scopeId: runId,\n node,\n registrationIndex,\n }),\n );\n }\n }\n {\n const errors = [\n ...cleanupExecutionErrors,\n ...teardownErrors.slice(priorTeardownErrors),\n ];\n if (errors.length)\n throw new AggregateError(errors, 'Case cleanup failed');\n }\n };\n try {\n if (phases.afterEach.length || teardownStack.length)\n await cleanupScopeResources(scopeSignal, cleanup, {\n totalTimeoutMs: options.teardownTimeoutMs?.(),\n beforeCleanup: async (cleanupSignal) => {\n try {\n await runPhase('afterEach', afterEach, cleanupSignal);\n } catch (error) {\n executionErrors.push(error);\n cleanupExecutionErrors.push(error);\n }\n },\n onDeferredError: (error) =>\n getDebug('runner:cleanup', { console: true })(\n `Deferred Case cleanup failed: ${String(error)}`,\n ),\n });\n else acceptingTeardowns = false;\n } catch (error) {\n deferredCleanup = error instanceof ResourceCleanupDeferredError;\n if (!deferredCleanup) acceptingTeardowns = false;\n if (\n !deferredCleanup &&\n !teardownErrors.length &&\n !cleanupExecutionErrors.length\n )\n teardownErrors.push(\n new NodeScopeTeardownError(error, {\n scope: 'case',\n scopeId: runId,\n node: 'resource-drain',\n registrationIndex: -1,\n }),\n );\n }\n const endedAt = new Date();\n const cleanupSnapshot = getResourceCleanupSnapshot(scopeSignal);\n const pendingOperations = getPendingScopeOperations(scopeSignal);\n const phaseResults = {\n beforeEach: phaseResult(phases.beforeEach.length, beforeEach),\n steps: phaseResult(phases.steps.length, steps),\n afterEach: phaseResult(phases.afterEach.length, afterEach),\n };\n const result: CaseRunResult = {\n caseId: collectedCase.caseId,\n runId,\n projectName: options.projectName ?? collectedCase.projectId,\n attemptIndex: options.attemptIndex ?? 0,\n name: collectedCase.definition.name,\n sourcePath: collectedCase.sourcePath,\n caseIndex: collectedCase.caseIndex,\n status:\n executionErrors.length > 0 ||\n beforeEach.some((step) => step.status !== 'success') ||\n steps.some((step) => step.status !== 'success') ||\n afterEach.some((step) => step.status !== 'success') ||\n cleanupSnapshot.status === 'pending' ||\n cleanupSnapshot.status === 'failed' ||\n pendingOperations.length > 0 ||\n teardownErrors.length > 0\n ? 'failed'\n : 'success',\n beforeEach: [...beforeEach],\n steps: [...steps],\n afterEach: [...afterEach],\n executionStatus: Object.values(phaseResults).some(\n (phase) => phase.status === 'failed',\n )\n ? 'failed'\n : Object.values(phaseResults).some((phase) => phase.status === 'not-run')\n ? 'not-run'\n : 'success',\n phases: phaseResults,\n cleanup: cleanupSnapshot,\n ...(pendingOperations.length ? { pendingOperations } : {}),\n ...(executionErrors.length\n ? { executionErrors: executionErrors.map(asExecutionError) }\n : {}),\n ...(teardownErrors.length > 0\n ? { teardownErrors: [...teardownErrors] }\n : {}),\n ...(reportPaths.size > 0 ? { reportPaths: [...reportPaths] } : {}),\n ...(capturedSources.size || reportSources.length\n ? { reportSources: [...capturedSources.values(), ...reportSources] }\n : {}),\n ...(options.reportScopeId ? { reportScopeId: options.reportScopeId } : {}),\n startedAt: startedAt.toISOString(),\n endedAt: endedAt.toISOString(),\n durationMs: Math.max(0, endedAt.getTime() - startedAt.getTime()),\n };\n\n try {\n await options.onResult?.(result);\n } catch (error) {\n executionErrors.push(error);\n result.status = 'failed';\n result.executionErrors = executionErrors.map(asExecutionError);\n }\n resourceScope.dispose();\n if (executionErrors.length)\n throw new WorkflowExecutionFailure(result, executionErrors);\n return result;\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","runCollectedCase","collectedCase","options","phases","nodes","step","resourceScope","createResourceScope","scopeSignal","runId","randomUUID","startedAt","Date","setResourceOperationIdentity","beforeEach","steps","afterEach","capturedSources","Map","teardownStack","acceptingTeardowns","onTeardown","node","teardown","WorkflowLifecycleError","runPhase","phase","results","signal","stepIndex","waitForPreviousOperationMs","recoverCancelledScopeResources","caseContext","stepInfo","result","executeStep","source","executionErrors","error","teardownErrors","reportPaths","Set","reportSources","cleanupExecutionErrors","deferredCleanup","cleanup","priorTeardownErrors","registrationIndex","released","path","reportPathsFromTeardown","NodeScopeTeardownError","errors","AggregateError","cleanupScopeResources","cleanupSignal","getDebug","String","ResourceCleanupDeferredError","endedAt","cleanupSnapshot","getResourceCleanupSnapshot","pendingOperations","getPendingScopeOperations","phaseResults","phaseResult","asExecutionError","Math","WorkflowExecutionFailure"],"mappings":"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"}
@@ -60,6 +60,8 @@ async function runWorkflowDocument(document, options) {
60
60
  }
61
61
  }),
62
62
  documentSetup: options.documentSetup,
63
+ setupTimeoutMs: options.setupTimeoutMs,
64
+ teardownTimeoutMs: options.teardownTimeoutMs,
63
65
  documentAttemptIndex: options.documentAttemptIndex,
64
66
  resolveNode: options.resolveNode,
65
67
  project: options.project,
@@ -104,6 +106,7 @@ async function runWorkflowDocument(document, options) {
104
106
  attemptIndex,
105
107
  signal: runtime.signal,
106
108
  defaultTimeoutMs: options.defaultTimeoutMs,
109
+ teardownTimeoutMs: options.teardownTimeoutMs,
107
110
  onStepStart: options.onStepStart,
108
111
  onStepResult: options.onStepResult,
109
112
  onResult: async (result)=>{
@@ -1 +1 @@
1
- {"version":3,"file":"test-runner/engine/run-workflow-document.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/test-runner/engine/run-workflow-document.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 { isResourceRecoveryError } from '../errors';\nimport type { CollectedCase, CollectedWorkflowDocument } from '../parser/types';\nimport { buildTestRunReportPlan } from '../reporting/test-plan';\nimport { createDocumentRuntime } from './document-runtime';\nimport {\n WorkflowExecutionFailure,\n asExecutionError,\n} from './execution-failure';\nimport { decideRetry } from './result-metadata';\nimport { runCollectedCase } from './run-collected-case';\nimport type {\n CaseRunOutcome,\n CaseRunResult,\n RunWorkflowDocumentOptions,\n WorkflowDocumentExecutionResult,\n WorkflowDocumentRunResult,\n} from './types';\n\nconst asNotRun = (\n collectedCase: CollectedCase,\n projectName: string,\n reason: NonNullable<CaseRunOutcome['notRunReason']>,\n): CaseRunOutcome => ({\n caseId: collectedCase.caseId,\n projectName,\n name: collectedCase.definition.name,\n sourcePath: collectedCase.sourcePath,\n caseIndex: collectedCase.caseIndex,\n ...(collectedCase.definition.onFailure\n ? { onFailure: collectedCase.definition.onFailure }\n : {}),\n status: 'not-run',\n notRunReason: reason,\n});\n\nexport async function runWorkflowDocument<TContext = undefined>(\n document: CollectedWorkflowDocument,\n options: RunWorkflowDocumentOptions<TContext>,\n): Promise<WorkflowDocumentExecutionResult> {\n const signal = options.signal ?? new AbortController().signal;\n const createDocumentRunId = options.createDocumentRunId;\n const createCaseRunId = options.createCaseRunId;\n const projectName = options.project?.name ?? document.projectId;\n const retry = options.retry ?? options.project?.retry ?? 0;\n if (!Number.isInteger(retry) || retry < 0) {\n throw new TypeError(\n 'Workflow document retry must be a non-negative integer.',\n );\n }\n const runtime = createDocumentRuntime(document, {\n plan:\n options.plan ??\n buildTestRunReportPlan(document, {\n defaultTimeoutMs: options.defaultTimeoutMs,\n retry: { scope: 'case', count: retry },\n }),\n documentSetup: options.documentSetup,\n documentAttemptIndex: options.documentAttemptIndex,\n resolveNode: options.resolveNode,\n project: options.project,\n projectContext: options.projectContext,\n signal,\n defaultTimeoutMs: options.defaultTimeoutMs,\n onStepStart: options.onStepStart,\n onStepResult: options.onStepResult,\n onResult: async (result) => {\n await options.documentSetup?.onDocumentResult?.(result, runtime.context);\n await options.onDocumentResult?.(result);\n },\n createDocumentRunId: createDocumentRunId\n ? () => createDocumentRunId(document)\n : undefined,\n });\n const cases: CaseRunOutcome[] = [];\n let runtimeStarted = false;\n let documentResult: WorkflowDocumentRunResult | undefined;\n const executionErrors: unknown[] = [];\n let fatalError = false;\n let documentStopReason: CaseRunOutcome['notRunReason'];\n\n try {\n runtimeStarted = true;\n const startedDocument = await runtime.start();\n\n if (!runtime.canRunCases) {\n const reason = signal.aborted\n ? (options.stopReason?.() ?? 'interrupted')\n : 'document-start-failed';\n cases.push(\n ...document.cases.map((collectedCase) =>\n asNotRun(collectedCase, projectName, reason),\n ),\n );\n } else {\n for (const collectedCase of document.cases) {\n if (\n documentStopReason ||\n fatalError ||\n signal.aborted ||\n options.shouldStop?.()\n ) {\n const outcome = asNotRun(\n collectedCase,\n projectName,\n signal.aborted\n ? (options.stopReason?.() ?? 'interrupted')\n : fatalError\n ? 'fatal-error'\n : (documentStopReason ??\n options.stopReason?.() ??\n 'interrupted'),\n );\n cases.push(outcome);\n await options.onCaseOutcome?.(outcome);\n continue;\n }\n\n await options.onCaseStart?.(collectedCase);\n const attempts = [];\n for (let attemptIndex = 0; attemptIndex <= retry; attemptIndex += 1) {\n let attemptFatalError = false;\n let attemptFailure:\n | WorkflowExecutionFailure<CaseRunResult>\n | undefined;\n const run = await runCollectedCase(collectedCase, {\n resolveNode: options.resolveNode,\n beforeEach: document.lifecycle.beforeEach,\n afterEach: document.lifecycle.afterEach,\n context: runtime.context,\n projectName,\n attemptIndex,\n signal: runtime.signal,\n defaultTimeoutMs: options.defaultTimeoutMs,\n onStepStart: options.onStepStart,\n onStepResult: options.onStepResult,\n onResult: async (result) => {\n attemptFatalError = options.isFatalError?.(result) ?? false;\n result.retryDecision = decideRetry({\n scope: 'case',\n retryCount: retry,\n attemptIndex,\n status: result.status,\n cleanupPending: result.cleanup?.status === 'pending',\n operationPending: !!result.pendingOperations?.length,\n cleanupFailed:\n result.cleanup?.status === 'failed' ||\n !!result.teardownErrors?.length,\n infrastructureError: result.executionErrors?.some(\n (error) => !isResourceRecoveryError(error),\n ),\n fatalError: attemptFatalError,\n interrupted: signal.aborted,\n shouldStop: options.shouldStop?.(),\n });\n await options.onCaseResult?.(result);\n },\n reportScopeId: options.resolveCaseReportScopeId?.(\n collectedCase,\n attemptIndex,\n startedDocument.documentRunId,\n ),\n createRunId: createCaseRunId\n ? () => createCaseRunId(collectedCase, attemptIndex)\n : undefined,\n }).catch((error: unknown) => {\n if (!(error instanceof WorkflowExecutionFailure)) throw error;\n attemptFailure = error as WorkflowExecutionFailure<CaseRunResult>;\n return attemptFailure.result;\n });\n attempts.push(run);\n if (\n attemptFailure &&\n !attemptFailure.errors.every(isResourceRecoveryError)\n ) {\n run.retryDecision = decideRetry({\n scope: 'case',\n retryCount: retry,\n attemptIndex,\n status: run.status,\n infrastructureError: true,\n });\n cases.push({\n caseId: collectedCase.caseId,\n projectName,\n name: collectedCase.definition.name,\n sourcePath: collectedCase.sourcePath,\n caseIndex: collectedCase.caseIndex,\n ...(collectedCase.definition.onFailure\n ? { onFailure: collectedCase.definition.onFailure }\n : {}),\n status: 'failed',\n run,\n attempts,\n });\n throw attemptFailure;\n }\n fatalError = attemptFatalError;\n // Result callbacks can interrupt execution or trigger bail. Observe\n // that boundary again before admitting another attempt.\n run.retryDecision = decideRetry({\n scope: 'case',\n retryCount: retry,\n attemptIndex,\n status: run.status,\n cleanupPending: run.cleanup?.status === 'pending',\n cleanupFailed:\n run.cleanup?.status === 'failed' || !!run.teardownErrors?.length,\n operationPending: !!run.pendingOperations?.length,\n fatalError:\n fatalError ||\n !!run.executionErrors?.some(isResourceRecoveryError),\n interrupted: signal.aborted,\n shouldStop: options.shouldStop?.(),\n });\n if (run.retryDecision?.decision !== 'retry') break;\n }\n const run = attempts.at(-1)!;\n const outcome: CaseRunOutcome = {\n caseId: collectedCase.caseId,\n projectName,\n name: collectedCase.definition.name,\n sourcePath: collectedCase.sourcePath,\n caseIndex: collectedCase.caseIndex,\n ...(collectedCase.definition.onFailure\n ? { onFailure: collectedCase.definition.onFailure }\n : {}),\n status: run.status,\n run,\n attempts,\n };\n cases.push(outcome);\n const retryStopReason = run.retryDecision?.reason;\n documentStopReason =\n retryStopReason === 'cleanup-pending' ||\n retryStopReason === 'cleanup-failed' ||\n retryStopReason === 'operation-pending' ||\n retryStopReason === 'fatal-error'\n ? retryStopReason\n : outcome.status === 'failed' &&\n collectedCase.definition.onFailure === 'stop-document'\n ? 'bail'\n : undefined;\n await options.onCaseOutcome?.(outcome);\n }\n }\n } catch (error) {\n executionErrors.push(\n ...(error instanceof WorkflowExecutionFailure ? error.errors : [error]),\n );\n } finally {\n if (runtimeStarted) {\n try {\n documentResult = await runtime.finish();\n } catch (error) {\n if (error instanceof WorkflowExecutionFailure) {\n documentResult = error.result as WorkflowDocumentRunResult;\n for (const failure of error.errors)\n if (!executionErrors.includes(failure))\n executionErrors.push(failure);\n } else executionErrors.push(error);\n }\n }\n }\n\n if (!documentResult) {\n if (executionErrors.length)\n throw new AggregateError(\n executionErrors,\n 'Workflow execution did not produce a document result.',\n );\n throw new Error(\n `Workflow document \"${document.sourcePath}\" did not produce a result.`,\n );\n }\n if (executionErrors.length) {\n const completed = new Set(cases.map((outcome) => outcome.caseId));\n cases.push(\n ...document.cases\n .filter((item) => !completed.has(item.caseId))\n .map((item) =>\n asNotRun(\n item,\n projectName,\n executionErrors.every(isResourceRecoveryError)\n ? 'operation-pending'\n : 'interrupted',\n ),\n ),\n );\n documentResult.status = 'failed';\n documentResult.executionErrors = executionErrors\n .filter(\n (error) =>\n !documentResult.hostErrors?.some((host) => host.error === error),\n )\n .map(asExecutionError);\n throw new WorkflowExecutionFailure(\n { document: documentResult, cases },\n executionErrors,\n );\n }\n return { document: documentResult, cases };\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","asNotRun","collectedCase","projectName","reason","runWorkflowDocument","document","options","signal","AbortController","createDocumentRunId","createCaseRunId","retry","Number","TypeError","runtime","createDocumentRuntime","buildTestRunReportPlan","result","undefined","cases","runtimeStarted","documentResult","executionErrors","fatalError","documentStopReason","startedDocument","outcome","attempts","attemptIndex","attemptFatalError","attemptFailure","run","runCollectedCase","decideRetry","error","isResourceRecoveryError","WorkflowExecutionFailure","retryStopReason","failure","AggregateError","Error","completed","Set","item","host","asExecutionError"],"mappings":"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"}
1
+ {"version":3,"file":"test-runner/engine/run-workflow-document.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/test-runner/engine/run-workflow-document.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 { isResourceRecoveryError } from '../errors';\nimport type { CollectedCase, CollectedWorkflowDocument } from '../parser/types';\nimport { buildTestRunReportPlan } from '../reporting/test-plan';\nimport { createDocumentRuntime } from './document-runtime';\nimport {\n WorkflowExecutionFailure,\n asExecutionError,\n} from './execution-failure';\nimport { decideRetry } from './result-metadata';\nimport { runCollectedCase } from './run-collected-case';\nimport type {\n CaseRunOutcome,\n CaseRunResult,\n RunWorkflowDocumentOptions,\n WorkflowDocumentExecutionResult,\n WorkflowDocumentRunResult,\n} from './types';\n\nconst asNotRun = (\n collectedCase: CollectedCase,\n projectName: string,\n reason: NonNullable<CaseRunOutcome['notRunReason']>,\n): CaseRunOutcome => ({\n caseId: collectedCase.caseId,\n projectName,\n name: collectedCase.definition.name,\n sourcePath: collectedCase.sourcePath,\n caseIndex: collectedCase.caseIndex,\n ...(collectedCase.definition.onFailure\n ? { onFailure: collectedCase.definition.onFailure }\n : {}),\n status: 'not-run',\n notRunReason: reason,\n});\n\nexport async function runWorkflowDocument<TContext = undefined>(\n document: CollectedWorkflowDocument,\n options: RunWorkflowDocumentOptions<TContext>,\n): Promise<WorkflowDocumentExecutionResult> {\n const signal = options.signal ?? new AbortController().signal;\n const createDocumentRunId = options.createDocumentRunId;\n const createCaseRunId = options.createCaseRunId;\n const projectName = options.project?.name ?? document.projectId;\n const retry = options.retry ?? options.project?.retry ?? 0;\n if (!Number.isInteger(retry) || retry < 0) {\n throw new TypeError(\n 'Workflow document retry must be a non-negative integer.',\n );\n }\n const runtime = createDocumentRuntime(document, {\n plan:\n options.plan ??\n buildTestRunReportPlan(document, {\n defaultTimeoutMs: options.defaultTimeoutMs,\n retry: { scope: 'case', count: retry },\n }),\n documentSetup: options.documentSetup,\n setupTimeoutMs: options.setupTimeoutMs,\n teardownTimeoutMs: options.teardownTimeoutMs,\n documentAttemptIndex: options.documentAttemptIndex,\n resolveNode: options.resolveNode,\n project: options.project,\n projectContext: options.projectContext,\n signal,\n defaultTimeoutMs: options.defaultTimeoutMs,\n onStepStart: options.onStepStart,\n onStepResult: options.onStepResult,\n onResult: async (result) => {\n await options.documentSetup?.onDocumentResult?.(result, runtime.context);\n await options.onDocumentResult?.(result);\n },\n createDocumentRunId: createDocumentRunId\n ? () => createDocumentRunId(document)\n : undefined,\n });\n const cases: CaseRunOutcome[] = [];\n let runtimeStarted = false;\n let documentResult: WorkflowDocumentRunResult | undefined;\n const executionErrors: unknown[] = [];\n let fatalError = false;\n let documentStopReason: CaseRunOutcome['notRunReason'];\n\n try {\n runtimeStarted = true;\n const startedDocument = await runtime.start();\n\n if (!runtime.canRunCases) {\n const reason = signal.aborted\n ? (options.stopReason?.() ?? 'interrupted')\n : 'document-start-failed';\n cases.push(\n ...document.cases.map((collectedCase) =>\n asNotRun(collectedCase, projectName, reason),\n ),\n );\n } else {\n for (const collectedCase of document.cases) {\n if (\n documentStopReason ||\n fatalError ||\n signal.aborted ||\n options.shouldStop?.()\n ) {\n const outcome = asNotRun(\n collectedCase,\n projectName,\n signal.aborted\n ? (options.stopReason?.() ?? 'interrupted')\n : fatalError\n ? 'fatal-error'\n : (documentStopReason ??\n options.stopReason?.() ??\n 'interrupted'),\n );\n cases.push(outcome);\n await options.onCaseOutcome?.(outcome);\n continue;\n }\n\n await options.onCaseStart?.(collectedCase);\n const attempts = [];\n for (let attemptIndex = 0; attemptIndex <= retry; attemptIndex += 1) {\n let attemptFatalError = false;\n let attemptFailure:\n | WorkflowExecutionFailure<CaseRunResult>\n | undefined;\n const run = await runCollectedCase(collectedCase, {\n resolveNode: options.resolveNode,\n beforeEach: document.lifecycle.beforeEach,\n afterEach: document.lifecycle.afterEach,\n context: runtime.context,\n projectName,\n attemptIndex,\n signal: runtime.signal,\n defaultTimeoutMs: options.defaultTimeoutMs,\n teardownTimeoutMs: options.teardownTimeoutMs,\n onStepStart: options.onStepStart,\n onStepResult: options.onStepResult,\n onResult: async (result) => {\n attemptFatalError = options.isFatalError?.(result) ?? false;\n result.retryDecision = decideRetry({\n scope: 'case',\n retryCount: retry,\n attemptIndex,\n status: result.status,\n cleanupPending: result.cleanup?.status === 'pending',\n operationPending: !!result.pendingOperations?.length,\n cleanupFailed:\n result.cleanup?.status === 'failed' ||\n !!result.teardownErrors?.length,\n infrastructureError: result.executionErrors?.some(\n (error) => !isResourceRecoveryError(error),\n ),\n fatalError: attemptFatalError,\n interrupted: signal.aborted,\n shouldStop: options.shouldStop?.(),\n });\n await options.onCaseResult?.(result);\n },\n reportScopeId: options.resolveCaseReportScopeId?.(\n collectedCase,\n attemptIndex,\n startedDocument.documentRunId,\n ),\n createRunId: createCaseRunId\n ? () => createCaseRunId(collectedCase, attemptIndex)\n : undefined,\n }).catch((error: unknown) => {\n if (!(error instanceof WorkflowExecutionFailure)) throw error;\n attemptFailure = error as WorkflowExecutionFailure<CaseRunResult>;\n return attemptFailure.result;\n });\n attempts.push(run);\n if (\n attemptFailure &&\n !attemptFailure.errors.every(isResourceRecoveryError)\n ) {\n run.retryDecision = decideRetry({\n scope: 'case',\n retryCount: retry,\n attemptIndex,\n status: run.status,\n infrastructureError: true,\n });\n cases.push({\n caseId: collectedCase.caseId,\n projectName,\n name: collectedCase.definition.name,\n sourcePath: collectedCase.sourcePath,\n caseIndex: collectedCase.caseIndex,\n ...(collectedCase.definition.onFailure\n ? { onFailure: collectedCase.definition.onFailure }\n : {}),\n status: 'failed',\n run,\n attempts,\n });\n throw attemptFailure;\n }\n fatalError = attemptFatalError;\n // Result callbacks can interrupt execution or trigger bail. Observe\n // that boundary again before admitting another attempt.\n run.retryDecision = decideRetry({\n scope: 'case',\n retryCount: retry,\n attemptIndex,\n status: run.status,\n cleanupPending: run.cleanup?.status === 'pending',\n cleanupFailed:\n run.cleanup?.status === 'failed' || !!run.teardownErrors?.length,\n operationPending: !!run.pendingOperations?.length,\n fatalError:\n fatalError ||\n !!run.executionErrors?.some(isResourceRecoveryError),\n interrupted: signal.aborted,\n shouldStop: options.shouldStop?.(),\n });\n if (run.retryDecision?.decision !== 'retry') break;\n }\n const run = attempts.at(-1)!;\n const outcome: CaseRunOutcome = {\n caseId: collectedCase.caseId,\n projectName,\n name: collectedCase.definition.name,\n sourcePath: collectedCase.sourcePath,\n caseIndex: collectedCase.caseIndex,\n ...(collectedCase.definition.onFailure\n ? { onFailure: collectedCase.definition.onFailure }\n : {}),\n status: run.status,\n run,\n attempts,\n };\n cases.push(outcome);\n const retryStopReason = run.retryDecision?.reason;\n documentStopReason =\n retryStopReason === 'cleanup-pending' ||\n retryStopReason === 'cleanup-failed' ||\n retryStopReason === 'operation-pending' ||\n retryStopReason === 'fatal-error'\n ? retryStopReason\n : outcome.status === 'failed' &&\n collectedCase.definition.onFailure === 'stop-document'\n ? 'bail'\n : undefined;\n await options.onCaseOutcome?.(outcome);\n }\n }\n } catch (error) {\n executionErrors.push(\n ...(error instanceof WorkflowExecutionFailure ? error.errors : [error]),\n );\n } finally {\n if (runtimeStarted) {\n try {\n documentResult = await runtime.finish();\n } catch (error) {\n if (error instanceof WorkflowExecutionFailure) {\n documentResult = error.result as WorkflowDocumentRunResult;\n for (const failure of error.errors)\n if (!executionErrors.includes(failure))\n executionErrors.push(failure);\n } else executionErrors.push(error);\n }\n }\n }\n\n if (!documentResult) {\n if (executionErrors.length)\n throw new AggregateError(\n executionErrors,\n 'Workflow execution did not produce a document result.',\n );\n throw new Error(\n `Workflow document \"${document.sourcePath}\" did not produce a result.`,\n );\n }\n if (executionErrors.length) {\n const completed = new Set(cases.map((outcome) => outcome.caseId));\n cases.push(\n ...document.cases\n .filter((item) => !completed.has(item.caseId))\n .map((item) =>\n asNotRun(\n item,\n projectName,\n executionErrors.every(isResourceRecoveryError)\n ? 'operation-pending'\n : 'interrupted',\n ),\n ),\n );\n documentResult.status = 'failed';\n documentResult.executionErrors = executionErrors\n .filter(\n (error) =>\n !documentResult.hostErrors?.some((host) => host.error === error),\n )\n .map(asExecutionError);\n throw new WorkflowExecutionFailure(\n { document: documentResult, cases },\n executionErrors,\n );\n }\n return { document: documentResult, cases };\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","asNotRun","collectedCase","projectName","reason","runWorkflowDocument","document","options","signal","AbortController","createDocumentRunId","createCaseRunId","retry","Number","TypeError","runtime","createDocumentRuntime","buildTestRunReportPlan","result","undefined","cases","runtimeStarted","documentResult","executionErrors","fatalError","documentStopReason","startedDocument","outcome","attempts","attemptIndex","attemptFatalError","attemptFailure","run","runCollectedCase","decideRetry","error","isResourceRecoveryError","WorkflowExecutionFailure","retryStopReason","failure","AggregateError","Error","completed","Set","item","host","asExecutionError"],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ runSetupWithTimeout: ()=>runSetupWithTimeout
28
+ });
29
+ const external_errors_js_namespaceObject = require("../errors.js");
30
+ const external_resource_operations_js_namespaceObject = require("./resource-operations.js");
31
+ async function runSetupWithTimeout(setup, signal, abort, timeoutMs) {
32
+ if (void 0 === timeoutMs) return setup();
33
+ signal.throwIfAborted();
34
+ const operation = Promise.resolve().then(setup);
35
+ (0, external_resource_operations_js_namespaceObject.trackResourceOperation)({}, operation, signal);
36
+ let timer;
37
+ let onAbort;
38
+ const stopped = new Promise((_resolve, reject)=>{
39
+ onAbort = ()=>reject(signal.reason);
40
+ signal.addEventListener('abort', onAbort, {
41
+ once: true
42
+ });
43
+ timer = setTimeout(()=>{
44
+ const error = new external_errors_js_namespaceObject.WorkflowError(`Environment setup timed out after ${timeoutMs}ms.`, {
45
+ code: 'SETUP_TIMEOUT',
46
+ details: {
47
+ timeoutMs
48
+ }
49
+ });
50
+ abort(error);
51
+ }, timeoutMs);
52
+ });
53
+ try {
54
+ return await Promise.race([
55
+ operation,
56
+ stopped
57
+ ]);
58
+ } finally{
59
+ clearTimeout(timer);
60
+ signal.removeEventListener('abort', onAbort);
61
+ }
62
+ }
63
+ exports.runSetupWithTimeout = __webpack_exports__.runSetupWithTimeout;
64
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
65
+ "runSetupWithTimeout"
66
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
67
+ Object.defineProperty(exports, '__esModule', {
68
+ value: true
69
+ });
70
+
71
+ //# sourceMappingURL=setup-timeout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-runner/engine/setup-timeout.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/test-runner/engine/setup-timeout.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 { WorkflowError } from '../errors';\nimport { trackResourceOperation } from './resource-operations';\n\n/** Keep tracking a timed-out acquisition until it actually settles. */\nexport async function runSetupWithTimeout<T>(\n setup: () => Promise<T>,\n signal: AbortSignal,\n abort: (reason: unknown) => void,\n timeoutMs?: number,\n): Promise<T> {\n if (timeoutMs === undefined) return setup();\n signal.throwIfAborted();\n const operation = Promise.resolve().then(setup);\n trackResourceOperation({}, operation, signal);\n let timer: ReturnType<typeof setTimeout> | undefined;\n let onAbort!: () => void;\n const stopped = new Promise<never>((_resolve, reject) => {\n onAbort = () => reject(signal.reason);\n signal.addEventListener('abort', onAbort, { once: true });\n timer = setTimeout(() => {\n const error = new WorkflowError(\n `Environment setup timed out after ${timeoutMs}ms.`,\n {\n code: 'SETUP_TIMEOUT',\n details: { timeoutMs },\n },\n );\n abort(error);\n }, timeoutMs);\n });\n try {\n return await Promise.race([operation, stopped]);\n } finally {\n clearTimeout(timer);\n signal.removeEventListener('abort', onAbort);\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","runSetupWithTimeout","setup","signal","abort","timeoutMs","undefined","operation","Promise","trackResourceOperation","timer","onAbort","stopped","_resolve","reject","setTimeout","error","WorkflowError","clearTimeout"],"mappings":";;;IAAAA,oBAAoB,CAAC,GAAG,CAAC,UAASC;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGD,oBAAoB,CAAC,CAACC,YAAYC,QAAQ,CAACF,oBAAoB,CAAC,CAAC,UAASE,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAF,oBAAoB,CAAC,GAAG,CAACI,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFL,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,eAAlB,OAAOM,UAA0BA,OAAO,WAAW,EACrDH,OAAO,cAAc,CAAC,UAASG,OAAO,WAAW,EAAE;YAAE,OAAO;QAAS;QAEtEH,OAAO,cAAc,CAAC,UAAS,cAAc;YAAE,OAAO;QAAK;IAC5D;;;;;;;;;ACFO,eAAeI,oBACpBC,KAAuB,EACvBC,MAAmB,EACnBC,KAAgC,EAChCC,SAAkB;IAElB,IAAIA,AAAcC,WAAdD,WAAyB,OAAOH;IACpCC,OAAO,cAAc;IACrB,MAAMI,YAAYC,QAAQ,OAAO,GAAG,IAAI,CAACN;IACzCO,IAAAA,gDAAAA,sBAAAA,AAAAA,EAAuB,CAAC,GAAGF,WAAWJ;IACtC,IAAIO;IACJ,IAAIC;IACJ,MAAMC,UAAU,IAAIJ,QAAe,CAACK,UAAUC;QAC5CH,UAAU,IAAMG,OAAOX,OAAO,MAAM;QACpCA,OAAO,gBAAgB,CAAC,SAASQ,SAAS;YAAE,MAAM;QAAK;QACvDD,QAAQK,WAAW;YACjB,MAAMC,QAAQ,IAAIC,mCAAAA,aAAaA,CAC7B,CAAC,kCAAkC,EAAEZ,UAAU,GAAG,CAAC,EACnD;gBACE,MAAM;gBACN,SAAS;oBAAEA;gBAAU;YACvB;YAEFD,MAAMY;QACR,GAAGX;IACL;IACA,IAAI;QACF,OAAO,MAAMG,QAAQ,IAAI,CAAC;YAACD;YAAWK;SAAQ;IAChD,SAAU;QACRM,aAAaR;QACbP,OAAO,mBAAmB,CAAC,SAASQ;IACtC;AACF"}
package/dist/lib/utils.js CHANGED
@@ -228,7 +228,7 @@ function stringifyDumpData(data, indents) {
228
228
  return JSON.stringify(data, replacerForPageObject, indents);
229
229
  }
230
230
  function getVersion() {
231
- return "1.16.0";
231
+ return "1.16.1";
232
232
  }
233
233
  function debugLog(...message) {
234
234
  const debugMode = process.env[env_namespaceObject.MIDSCENE_DEBUG_MODE];
@@ -24,6 +24,7 @@ var __webpack_require__ = {};
24
24
  var __webpack_exports__ = {};
25
25
  __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
+ hasActiveYamlExecution: ()=>hasActiveYamlExecution,
27
28
  YamlExecutionOwnershipError: ()=>YamlExecutionOwnershipError,
28
29
  enterYamlExecution: ()=>enterYamlExecution,
29
30
  runInYamlExecutionContext: ()=>runInYamlExecutionContext,
@@ -40,6 +41,7 @@ host[stateKey] ??= {
40
41
  context: (0, external_yaml_execution_context_namespaceObject.createExecutionContext)()
41
42
  };
42
43
  const { sessions, signals, context } = host[stateKey];
44
+ const hasActiveYamlExecution = (agent)=>Boolean(sessions.get(agent)?.length);
43
45
  function runInYamlExecutionContext(callback) {
44
46
  const frame = {
45
47
  parent: context.getStore(),
@@ -121,12 +123,14 @@ exports.YamlExecutionOwnershipError = __webpack_exports__.YamlExecutionOwnership
121
123
  exports.currentYamlSignal = __webpack_exports__.currentYamlSignal;
122
124
  exports.enterYamlAction = __webpack_exports__.enterYamlAction;
123
125
  exports.enterYamlExecution = __webpack_exports__.enterYamlExecution;
126
+ exports.hasActiveYamlExecution = __webpack_exports__.hasActiveYamlExecution;
124
127
  exports.runInYamlExecutionContext = __webpack_exports__.runInYamlExecutionContext;
125
128
  for(var __rspack_i in __webpack_exports__)if (-1 === [
126
129
  "YamlExecutionOwnershipError",
127
130
  "currentYamlSignal",
128
131
  "enterYamlAction",
129
132
  "enterYamlExecution",
133
+ "hasActiveYamlExecution",
130
134
  "runInYamlExecutionContext"
131
135
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
132
136
  Object.defineProperty(exports, '__esModule', {
@@ -1 +1 @@
1
- {"version":3,"file":"yaml/execution-session.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/yaml/execution-session.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 createExecutionContext,\n supportsAsyncContext,\n} from '#yaml-execution-context';\nimport { WorkflowError } from '../test-runner/errors';\nimport type { WorkflowExecutionRecord } from '../test-runner/execution-record';\n\ninterface YamlExecutionSession {\n agent: object;\n children: WorkflowExecutionRecord[];\n finished: boolean;\n finish(record?: WorkflowExecutionRecord): void;\n}\n\ninterface ExecutionFrame {\n parent?: ExecutionFrame;\n session?: YamlExecutionSession;\n signals: WeakMap<object, { signal: AbortSignal }[]>;\n}\n\nconst stateKey = Symbol.for('@midscene/core/yaml-execution-session/v2');\nconst host = globalThis as typeof globalThis & {\n [stateKey]?: {\n sessions: WeakMap<object, YamlExecutionSession[]>;\n signals: WeakMap<object, { signal: AbortSignal }[]>;\n context: ReturnType<typeof createExecutionContext<ExecutionFrame>>;\n };\n};\nhost[stateKey] ??= {\n sessions: new WeakMap(),\n signals: new WeakMap(),\n context: createExecutionContext<ExecutionFrame>(),\n};\nconst { sessions, signals, context } = host[stateKey];\n\n/** Every entry gets its own async frame, shared across CJS and ESM copies. */\nexport function runInYamlExecutionContext<T>(\n callback: () => Promise<T>,\n): Promise<T> {\n const frame: ExecutionFrame = {\n parent: context.getStore(),\n signals: new WeakMap(),\n };\n return context.run(frame, async () => {\n try {\n return await callback();\n } finally {\n frame.session?.finish();\n }\n });\n}\n\nexport const currentYamlSignal = (agent: object): AbortSignal | undefined => {\n if (!supportsAsyncContext) return signals.get(agent)?.at(-1)?.signal;\n for (let frame = context.getStore(); frame; frame = frame.parent) {\n const signal = frame.signals.get(agent)?.at(-1)?.signal;\n if (signal) return signal;\n }\n return undefined;\n};\n\nexport function enterYamlAction(\n agent: object,\n signal: AbortSignal,\n): () => void {\n const scopeSignals = supportsAsyncContext\n ? context.getStore()?.signals\n : signals;\n if (!scopeSignals)\n throw new Error('YAML action requires an execution context.');\n const stack = scopeSignals.get(agent) ?? [];\n scopeSignals.set(agent, stack);\n const entry = { signal };\n stack.push(entry);\n return () => {\n const index = stack.indexOf(entry);\n if (index >= 0) stack.splice(index, 1);\n if (!stack.length) scopeSignals.delete(agent);\n };\n}\n\nexport class YamlExecutionOwnershipError extends WorkflowError {}\n\n/** Nested runs borrow ownership. They never finalize or drain their parent. */\nexport function enterYamlExecution(\n agent: object,\n options: { allowIndependentOverlap?: boolean } = {},\n) {\n const stack = sessions.get(agent) ?? [];\n const frame = context.getStore();\n let parent = supportsAsyncContext ? undefined : stack.at(-1);\n if (supportsAsyncContext) {\n if (!frame || frame.session)\n throw new Error('YAML execution requires a fresh execution context.');\n for (let owner = frame.parent; owner; owner = owner.parent) {\n if (owner.session?.agent === agent) {\n parent = owner.session;\n break;\n }\n }\n if (parent?.finished)\n throw new YamlExecutionOwnershipError(\n 'Cannot start nested YAML after its owning execution has finished.',\n { code: 'YAML_EXECUTION_SCOPE_CLOSED' },\n );\n if (stack.at(-1) !== parent && !options.allowIndependentOverlap)\n throw new YamlExecutionOwnershipError(\n 'The same Agent cannot run independent overlapping YAML executions. Await the active run before starting another.',\n { code: 'YAML_EXECUTION_OVERLAP' },\n );\n }\n const session: YamlExecutionSession = {\n agent,\n children: [],\n finished: false,\n finish(record?: WorkflowExecutionRecord) {\n if (session.finished) return;\n session.finished = true;\n const index = stack.indexOf(session);\n if (index >= 0) stack.splice(index, 1);\n if (!stack.length) sessions.delete(agent);\n if (record) parent?.children.push(record);\n else parent?.children.push(...session.children);\n },\n };\n stack.push(session);\n sessions.set(agent, stack);\n if (frame) frame.session = session;\n return {\n isRoot: !parent,\n children: session.children,\n finish: session.finish,\n };\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","stateKey","host","globalThis","WeakMap","createExecutionContext","sessions","signals","context","runInYamlExecutionContext","callback","frame","currentYamlSignal","agent","supportsAsyncContext","signal","enterYamlAction","scopeSignals","Error","stack","entry","index","YamlExecutionOwnershipError","WorkflowError","enterYamlExecution","options","parent","undefined","owner","session","record"],"mappings":"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"}
1
+ {"version":3,"file":"yaml/execution-session.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/yaml/execution-session.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 createExecutionContext,\n supportsAsyncContext,\n} from '#yaml-execution-context';\nimport { WorkflowError } from '../test-runner/errors';\nimport type { WorkflowExecutionRecord } from '../test-runner/execution-record';\n\ninterface YamlExecutionSession {\n agent: object;\n children: WorkflowExecutionRecord[];\n finished: boolean;\n finish(record?: WorkflowExecutionRecord): void;\n}\n\ninterface ExecutionFrame {\n parent?: ExecutionFrame;\n session?: YamlExecutionSession;\n signals: WeakMap<object, { signal: AbortSignal }[]>;\n}\n\nconst stateKey = Symbol.for('@midscene/core/yaml-execution-session/v2');\nconst host = globalThis as typeof globalThis & {\n [stateKey]?: {\n sessions: WeakMap<object, YamlExecutionSession[]>;\n signals: WeakMap<object, { signal: AbortSignal }[]>;\n context: ReturnType<typeof createExecutionContext<ExecutionFrame>>;\n };\n};\nhost[stateKey] ??= {\n sessions: new WeakMap(),\n signals: new WeakMap(),\n context: createExecutionContext<ExecutionFrame>(),\n};\nconst { sessions, signals, context } = host[stateKey];\n\n/** Report boundaries cannot change while a YAML owner still uses the Agent. */\nexport const hasActiveYamlExecution = (agent: object): boolean =>\n Boolean(sessions.get(agent)?.length);\n\n/** Every entry gets its own async frame, shared across CJS and ESM copies. */\nexport function runInYamlExecutionContext<T>(\n callback: () => Promise<T>,\n): Promise<T> {\n const frame: ExecutionFrame = {\n parent: context.getStore(),\n signals: new WeakMap(),\n };\n return context.run(frame, async () => {\n try {\n return await callback();\n } finally {\n frame.session?.finish();\n }\n });\n}\n\nexport const currentYamlSignal = (agent: object): AbortSignal | undefined => {\n if (!supportsAsyncContext) return signals.get(agent)?.at(-1)?.signal;\n for (let frame = context.getStore(); frame; frame = frame.parent) {\n const signal = frame.signals.get(agent)?.at(-1)?.signal;\n if (signal) return signal;\n }\n return undefined;\n};\n\nexport function enterYamlAction(\n agent: object,\n signal: AbortSignal,\n): () => void {\n const scopeSignals = supportsAsyncContext\n ? context.getStore()?.signals\n : signals;\n if (!scopeSignals)\n throw new Error('YAML action requires an execution context.');\n const stack = scopeSignals.get(agent) ?? [];\n scopeSignals.set(agent, stack);\n const entry = { signal };\n stack.push(entry);\n return () => {\n const index = stack.indexOf(entry);\n if (index >= 0) stack.splice(index, 1);\n if (!stack.length) scopeSignals.delete(agent);\n };\n}\n\nexport class YamlExecutionOwnershipError extends WorkflowError {}\n\n/** Nested runs borrow ownership. They never finalize or drain their parent. */\nexport function enterYamlExecution(\n agent: object,\n options: { allowIndependentOverlap?: boolean } = {},\n) {\n const stack = sessions.get(agent) ?? [];\n const frame = context.getStore();\n let parent = supportsAsyncContext ? undefined : stack.at(-1);\n if (supportsAsyncContext) {\n if (!frame || frame.session)\n throw new Error('YAML execution requires a fresh execution context.');\n for (let owner = frame.parent; owner; owner = owner.parent) {\n if (owner.session?.agent === agent) {\n parent = owner.session;\n break;\n }\n }\n if (parent?.finished)\n throw new YamlExecutionOwnershipError(\n 'Cannot start nested YAML after its owning execution has finished.',\n { code: 'YAML_EXECUTION_SCOPE_CLOSED' },\n );\n if (stack.at(-1) !== parent && !options.allowIndependentOverlap)\n throw new YamlExecutionOwnershipError(\n 'The same Agent cannot run independent overlapping YAML executions. Await the active run before starting another.',\n { code: 'YAML_EXECUTION_OVERLAP' },\n );\n }\n const session: YamlExecutionSession = {\n agent,\n children: [],\n finished: false,\n finish(record?: WorkflowExecutionRecord) {\n if (session.finished) return;\n session.finished = true;\n const index = stack.indexOf(session);\n if (index >= 0) stack.splice(index, 1);\n if (!stack.length) sessions.delete(agent);\n if (record) parent?.children.push(record);\n else parent?.children.push(...session.children);\n },\n };\n stack.push(session);\n sessions.set(agent, stack);\n if (frame) frame.session = session;\n return {\n isRoot: !parent,\n children: session.children,\n finish: session.finish,\n };\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","stateKey","host","globalThis","WeakMap","createExecutionContext","sessions","signals","context","hasActiveYamlExecution","agent","Boolean","runInYamlExecutionContext","callback","frame","currentYamlSignal","supportsAsyncContext","signal","enterYamlAction","scopeSignals","Error","stack","entry","index","YamlExecutionOwnershipError","WorkflowError","enterYamlExecution","options","parent","undefined","owner","session","record"],"mappings":";;;IAAAA,oBAAoB,CAAC,GAAG,CAAC,UAASC;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGD,oBAAoB,CAAC,CAACC,YAAYC,QAAQ,CAACF,oBAAoB,CAAC,CAAC,UAASE,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAF,oBAAoB,CAAC,GAAG,CAACI,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFL,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,eAAlB,OAAOM,UAA0BA,OAAO,WAAW,EACrDH,OAAO,cAAc,CAAC,UAASG,OAAO,WAAW,EAAE;YAAE,OAAO;QAAS;QAEtEH,OAAO,cAAc,CAAC,UAAS,cAAc;YAAE,OAAO;QAAK;IAC5D;;;;;;;;;;;;;;ACcA,MAAMI,WAAWD,OAAO,GAAG,CAAC;AAC5B,MAAME,OAAOC;AAObD,IAAI,CAACD,SAAS,KAAK;IACjB,UAAU,IAAIG;IACd,SAAS,IAAIA;IACb,SAASC,AAAAA,IAAAA,gDAAAA,sBAAAA,AAAAA;AACX;AACA,MAAM,EAAEC,QAAQ,EAAEC,OAAO,EAAEC,OAAO,EAAE,GAAGN,IAAI,CAACD,SAAS;AAG9C,MAAMQ,yBAAyB,CAACC,QACrCC,QAAQL,SAAS,GAAG,CAACI,QAAQ;AAGxB,SAASE,0BACdC,QAA0B;IAE1B,MAAMC,QAAwB;QAC5B,QAAQN,QAAQ,QAAQ;QACxB,SAAS,IAAIJ;IACf;IACA,OAAOI,QAAQ,GAAG,CAACM,OAAO;QACxB,IAAI;YACF,OAAO,MAAMD;QACf,SAAU;YACRC,MAAM,OAAO,EAAE;QACjB;IACF;AACF;AAEO,MAAMC,oBAAoB,CAACL;IAChC,IAAI,CAACM,gDAAAA,oBAAoBA,EAAE,OAAOT,QAAQ,GAAG,CAACG,QAAQ,GAAG,KAAK;IAC9D,IAAK,IAAII,QAAQN,QAAQ,QAAQ,IAAIM,OAAOA,QAAQA,MAAM,MAAM,CAAE;QAChE,MAAMG,SAASH,MAAM,OAAO,CAAC,GAAG,CAACJ,QAAQ,GAAG,KAAK;QACjD,IAAIO,QAAQ,OAAOA;IACrB;AAEF;AAEO,SAASC,gBACdR,KAAa,EACbO,MAAmB;IAEnB,MAAME,eAAeH,gDAAAA,oBAAoBA,GACrCR,QAAQ,QAAQ,IAAI,UACpBD;IACJ,IAAI,CAACY,cACH,MAAM,IAAIC,MAAM;IAClB,MAAMC,QAAQF,aAAa,GAAG,CAACT,UAAU,EAAE;IAC3CS,aAAa,GAAG,CAACT,OAAOW;IACxB,MAAMC,QAAQ;QAAEL;IAAO;IACvBI,MAAM,IAAI,CAACC;IACX,OAAO;QACL,MAAMC,QAAQF,MAAM,OAAO,CAACC;QAC5B,IAAIC,SAAS,GAAGF,MAAM,MAAM,CAACE,OAAO;QACpC,IAAI,CAACF,MAAM,MAAM,EAAEF,aAAa,MAAM,CAACT;IACzC;AACF;AAEO,MAAMc,oCAAoCC,0BAAAA,aAAaA;AAAE;AAGzD,SAASC,mBACdhB,KAAa,EACbiB,UAAiD,CAAC,CAAC;IAEnD,MAAMN,QAAQf,SAAS,GAAG,CAACI,UAAU,EAAE;IACvC,MAAMI,QAAQN,QAAQ,QAAQ;IAC9B,IAAIoB,SAASZ,gDAAAA,oBAAoBA,GAAGa,SAAYR,MAAM,EAAE,CAAC;IACzD,IAAIL,gDAAAA,oBAAoBA,EAAE;QACxB,IAAI,CAACF,SAASA,MAAM,OAAO,EACzB,MAAM,IAAIM,MAAM;QAClB,IAAK,IAAIU,QAAQhB,MAAM,MAAM,EAAEgB,OAAOA,QAAQA,MAAM,MAAM,CACxD,IAAIA,MAAM,OAAO,EAAE,UAAUpB,OAAO;YAClCkB,SAASE,MAAM,OAAO;YACtB;QACF;QAEF,IAAIF,QAAQ,UACV,MAAM,IAAIJ,4BACR,qEACA;YAAE,MAAM;QAA8B;QAE1C,IAAIH,MAAM,EAAE,CAAC,QAAQO,UAAU,CAACD,QAAQ,uBAAuB,EAC7D,MAAM,IAAIH,4BACR,oHACA;YAAE,MAAM;QAAyB;IAEvC;IACA,MAAMO,UAAgC;QACpCrB;QACA,UAAU,EAAE;QACZ,UAAU;QACV,QAAOsB,MAAgC;YACrC,IAAID,QAAQ,QAAQ,EAAE;YACtBA,QAAQ,QAAQ,GAAG;YACnB,MAAMR,QAAQF,MAAM,OAAO,CAACU;YAC5B,IAAIR,SAAS,GAAGF,MAAM,MAAM,CAACE,OAAO;YACpC,IAAI,CAACF,MAAM,MAAM,EAAEf,SAAS,MAAM,CAACI;YACnC,IAAIsB,QAAQJ,QAAQ,SAAS,KAAKI;iBAC7BJ,QAAQ,SAAS,QAAQG,QAAQ,QAAQ;QAChD;IACF;IACAV,MAAM,IAAI,CAACU;IACXzB,SAAS,GAAG,CAACI,OAAOW;IACpB,IAAIP,OAAOA,MAAM,OAAO,GAAGiB;IAC3B,OAAO;QACL,QAAQ,CAACH;QACT,UAAUG,QAAQ,QAAQ;QAC1B,QAAQA,QAAQ,MAAM;IACxB;AACF"}
@@ -62,8 +62,8 @@ async function publishLegacyYamlReport(options) {
62
62
  sdkVersion: (0, external_utils_js_namespaceObject.getVersion)(),
63
63
  modelBriefs: []
64
64
  });
65
- await generator.finalize();
66
65
  const source = await generator.createSourceSnapshot?.(runId);
66
+ await generator.finalize();
67
67
  if (source) record = Object.freeze({
68
68
  ...record,
69
69
  reportSources: [