callman-core 1.25.0 → 1.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/contract/contractValidator.d.ts.map +1 -1
- package/dist/contract/contractValidator.js +13 -4
- package/dist/contract/contractValidator.js.map +1 -1
- package/dist/host/db/mysqlAdapter.d.ts.map +1 -1
- package/dist/host/db/mysqlAdapter.js +39 -9
- package/dist/host/db/mysqlAdapter.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/request/executeRequest.d.ts +1 -1
- package/dist/request/executeRequest.d.ts.map +1 -1
- package/dist/request/executeRequest.js +8 -1
- package/dist/request/executeRequest.js.map +1 -1
- package/dist/runner/runCollection.d.ts.map +1 -1
- package/dist/runner/runCollection.js +8 -3
- package/dist/runner/runCollection.js.map +1 -1
- package/dist/scenario-runner/adapters/request-executor.js +12 -3
- package/dist/scenario-runner/adapters/request-executor.js.map +1 -1
- package/dist/scenario-runner/adapters/script-executor.js +1 -1
- package/dist/scenario-runner/adapters/script-executor.js.map +1 -1
- package/dist/scenario-runner/adapters/types.d.ts +1 -0
- package/dist/scenario-runner/adapters/types.d.ts.map +1 -1
- package/dist/scenario-runner/boundSnapshot.d.ts +15 -0
- package/dist/scenario-runner/boundSnapshot.d.ts.map +1 -0
- package/dist/scenario-runner/boundSnapshot.js +67 -0
- package/dist/scenario-runner/boundSnapshot.js.map +1 -0
- package/dist/scenario-runner/runScenario.d.ts +1 -1
- package/dist/scenario-runner/runScenario.d.ts.map +1 -1
- package/dist/scenario-runner/runScenario.js +42 -25
- package/dist/scenario-runner/runScenario.js.map +1 -1
- package/dist/scenario-runner/runScenarioWithDataset.d.ts.map +1 -1
- package/dist/scenario-runner/runScenarioWithDataset.js +21 -6
- package/dist/scenario-runner/runScenarioWithDataset.js.map +1 -1
- package/dist/scenario-runner/types.d.ts +10 -0
- package/dist/scenario-runner/types.d.ts.map +1 -1
- package/dist/script/isolated-runner.d.ts +7 -1
- package/dist/script/isolated-runner.d.ts.map +1 -1
- package/dist/script/isolated-runner.js +11 -5
- package/dist/script/isolated-runner.js.map +1 -1
- package/dist/script/worker-entry.js +62 -28
- package/dist/script/worker-entry.js.map +1 -1
- package/dist/script/worker-pool.d.ts +60 -0
- package/dist/script/worker-pool.d.ts.map +1 -0
- package/dist/script/worker-pool.js +274 -0
- package/dist/script/worker-pool.js.map +1 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist-cjs/contract/contractValidator.js +13 -4
- package/dist-cjs/contract/contractValidator.js.map +1 -1
- package/dist-cjs/host/db/mysqlAdapter.js +39 -9
- package/dist-cjs/host/db/mysqlAdapter.js.map +1 -1
- package/dist-cjs/index.js +4 -1
- package/dist-cjs/index.js.map +1 -1
- package/dist-cjs/request/executeRequest.js +8 -1
- package/dist-cjs/request/executeRequest.js.map +1 -1
- package/dist-cjs/runner/runCollection.js +8 -3
- package/dist-cjs/runner/runCollection.js.map +1 -1
- package/dist-cjs/scenario-runner/adapters/request-executor.js +12 -3
- package/dist-cjs/scenario-runner/adapters/request-executor.js.map +1 -1
- package/dist-cjs/scenario-runner/adapters/script-executor.js +1 -1
- package/dist-cjs/scenario-runner/adapters/script-executor.js.map +1 -1
- package/dist-cjs/scenario-runner/boundSnapshot.js +71 -0
- package/dist-cjs/scenario-runner/boundSnapshot.js.map +1 -0
- package/dist-cjs/scenario-runner/runScenario.js +42 -25
- package/dist-cjs/scenario-runner/runScenario.js.map +1 -1
- package/dist-cjs/scenario-runner/runScenarioWithDataset.js +21 -6
- package/dist-cjs/scenario-runner/runScenarioWithDataset.js.map +1 -1
- package/dist-cjs/script/isolated-runner.js +12 -5
- package/dist-cjs/script/isolated-runner.js.map +1 -1
- package/dist-cjs/script/worker-entry.js +62 -28
- package/dist-cjs/script/worker-entry.js.map +1 -1
- package/dist-cjs/script/worker-pool.js +312 -0
- package/dist-cjs/script/worker-pool.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Size-capped deep copy of a runtime value for event context snapshots
|
|
2
|
+
// (`RunScenarioOptions.eventContextMode: "bounded"`).
|
|
3
|
+
//
|
|
4
|
+
// The caps are deliberately LOOSER than the backend report mapper's persist-
|
|
5
|
+
// time truncation (16 KB strings / 50 array items / 50 keys / depth 6), so
|
|
6
|
+
// everything the mapper keeps is still present verbatim after bounding —
|
|
7
|
+
// the persisted report is byte-identical whether bounding ran or not. What
|
|
8
|
+
// changes is what stays in the HEAP while the run is in flight: a bounded
|
|
9
|
+
// snapshot never holds a reference to a multi-megabyte response body.
|
|
10
|
+
export const DEFAULT_BOUND_SNAPSHOT_LIMITS = {
|
|
11
|
+
maxStringLength: 32 * 1024,
|
|
12
|
+
maxArrayItems: 100,
|
|
13
|
+
maxObjectKeys: 100,
|
|
14
|
+
maxDepth: 8,
|
|
15
|
+
};
|
|
16
|
+
const TRUNCATED = "…[truncated]";
|
|
17
|
+
const boundValueAt = (value, depth, limits) => {
|
|
18
|
+
if (value === null || value === undefined)
|
|
19
|
+
return value;
|
|
20
|
+
switch (typeof value) {
|
|
21
|
+
case "string":
|
|
22
|
+
return value.length > limits.maxStringLength
|
|
23
|
+
? `${value.slice(0, limits.maxStringLength)}${TRUNCATED}`
|
|
24
|
+
: value;
|
|
25
|
+
case "number":
|
|
26
|
+
case "boolean":
|
|
27
|
+
return value;
|
|
28
|
+
case "bigint":
|
|
29
|
+
return value.toString();
|
|
30
|
+
case "function":
|
|
31
|
+
case "symbol":
|
|
32
|
+
return undefined;
|
|
33
|
+
default:
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
if (value instanceof Date)
|
|
37
|
+
return new Date(value.getTime());
|
|
38
|
+
if (depth >= limits.maxDepth)
|
|
39
|
+
return TRUNCATED;
|
|
40
|
+
if (Array.isArray(value)) {
|
|
41
|
+
const kept = value.slice(0, limits.maxArrayItems).map((item) => boundValueAt(item, depth + 1, limits));
|
|
42
|
+
return kept;
|
|
43
|
+
}
|
|
44
|
+
if (typeof value.toJSON === "function") {
|
|
45
|
+
return boundValueAt(value.toJSON(), depth, limits);
|
|
46
|
+
}
|
|
47
|
+
const out = {};
|
|
48
|
+
let count = 0;
|
|
49
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
50
|
+
if (count >= limits.maxObjectKeys)
|
|
51
|
+
break;
|
|
52
|
+
const bounded = boundValueAt(entry, depth + 1, limits);
|
|
53
|
+
if (bounded !== undefined) {
|
|
54
|
+
out[key] = bounded;
|
|
55
|
+
count += 1;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Returns a bounded deep copy of `value`. `undefined` and `null` pass
|
|
62
|
+
* through unchanged; typed callers cast the result back to their shape —
|
|
63
|
+
* bounding never changes the top-level structure, only trims what is nested
|
|
64
|
+
* inside it.
|
|
65
|
+
*/
|
|
66
|
+
export const boundSnapshot = (value, limits = DEFAULT_BOUND_SNAPSHOT_LIMITS) => (value === null || value === undefined ? value : boundValueAt(value, 0, limits));
|
|
67
|
+
//# sourceMappingURL=boundSnapshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boundSnapshot.js","sourceRoot":"","sources":["../../src/scenario-runner/boundSnapshot.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,sDAAsD;AACtD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,yEAAyE;AACzE,2EAA2E;AAC3E,0EAA0E;AAC1E,sEAAsE;AAStE,MAAM,CAAC,MAAM,6BAA6B,GAAwB;IAChE,eAAe,EAAE,EAAE,GAAG,IAAI;IAC1B,aAAa,EAAE,GAAG;IAClB,aAAa,EAAE,GAAG;IAClB,QAAQ,EAAE,CAAC;CACZ,CAAC;AAEF,MAAM,SAAS,GAAG,cAAc,CAAC;AAEjC,MAAM,YAAY,GAAG,CAAC,KAAc,EAAE,KAAa,EAAE,MAA2B,EAAW,EAAE;IAC3F,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACxD,QAAQ,OAAO,KAAK,EAAE,CAAC;QACrB,KAAK,QAAQ;YACX,OAAO,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,eAAe;gBAC1C,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,eAAe,CAAC,GAAG,SAAS,EAAE;gBACzD,CAAC,CAAC,KAAK,CAAC;QACZ,KAAK,QAAQ,CAAC;QACd,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC;QACf,KAAK,QAAQ;YACX,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC1B,KAAK,UAAU,CAAC;QAChB,KAAK,QAAQ;YACX,OAAO,SAAS,CAAC;QACnB;YACE,MAAM;IACV,CAAC;IACD,IAAI,KAAK,YAAY,IAAI;QAAE,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5D,IAAI,KAAK,IAAI,MAAM,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC/C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACvG,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,OAAQ,KAA8B,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QACjE,OAAO,YAAY,CAAE,KAAmC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACpF,CAAC;IACD,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,EAAE,CAAC;QAC5E,IAAI,KAAK,IAAI,MAAM,CAAC,aAAa;YAAE,MAAM;QACzC,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QACvD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,GAAG,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC;YACnB,KAAK,IAAI,CAAC,CAAC;QACb,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,KAAQ,EACR,SAA8B,6BAA6B,EACxD,EAAE,CAAC,CAAC,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,YAAY,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAO,CAAC,CAAC"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { RunScenarioOptions, ScenarioRunReport } from "./types.js";
|
|
2
|
-
export declare const runScenario: ({ scenario, environment, globals, runtimeAdapters, eventHandlers, signal, minNodeVisualStateMs, }: RunScenarioOptions) => Promise<ScenarioRunReport>;
|
|
2
|
+
export declare const runScenario: ({ scenario, environment, globals, runtimeAdapters, eventHandlers, signal, minNodeVisualStateMs, eventContextMode, }: RunScenarioOptions) => Promise<ScenarioRunReport>;
|
|
3
3
|
//# sourceMappingURL=runScenario.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runScenario.d.ts","sourceRoot":"","sources":["../../src/scenario-runner/runScenario.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runScenario.d.ts","sourceRoot":"","sources":["../../src/scenario-runner/runScenario.ts"],"names":[],"mappings":"AA2DA,OAAO,KAAK,EAMV,kBAAkB,EAUlB,iBAAiB,EAKlB,MAAM,YAAY,CAAC;AAmvBpB,eAAO,MAAM,WAAW,GAAU,qHAS/B,kBAAkB,KAAG,OAAO,CAAC,iBAAiB,CAggFhD,CAAC"}
|
|
@@ -4,6 +4,7 @@ import { evaluateAssertionConfig, validateAssertionConfig, } from "./assertion.j
|
|
|
4
4
|
import { createSubScenarioStepId, buildRuntimeStepDescriptors, DEFAULT_END_LOOP_DELAY_MS, DEFAULT_END_LOOP_ITERATIONS, flattenScenarioNodesForContext, MAX_END_LOOP_ITERATIONS, DEFAULT_POLL_INTERVAL_MS, DEFAULT_POLL_MAX_ATTEMPTS, MAX_POLL_ATTEMPTS, DEFAULT_FOREACH_MAX_ITERATIONS, MAX_FOREACH_ITERATIONS, DEFAULT_WS_CONNECT_TIMEOUT_MS, MAX_WS_CONNECT_TIMEOUT_MS, DEFAULT_WS_EXPECT_TIMEOUT_MS, MAX_WS_EXPECT_TIMEOUT_MS, MAX_WS_WAIT_DURATION_MS, MAX_WS_STEPS, DEFAULT_WS_CLOSE_CODE, } from "./graphTraversal.js";
|
|
5
5
|
import { evaluateWebsocketExpect } from "./websocket.js";
|
|
6
6
|
import { executeWithScenarioNodePolicy } from "./executionPolicyRunner.js";
|
|
7
|
+
import { boundSnapshot } from "./boundSnapshot.js";
|
|
7
8
|
import { getLegacyScenarioNodeExecutionPolicy, getScenarioNodeExecutionPolicy, supportsScenarioNodeExecutionPolicy, } from "./nodePolicy.js";
|
|
8
9
|
import { buildScenarioExecutionGraph, buildScenarioTemplateValues, collectExclusiveBranchNodeIds, evaluateScenarioExpression, resolveScenarioJsonTemplateString, resolveScenarioTemplateString, } from "./templateResolver.js";
|
|
9
10
|
import { executeWaitNode, ScenarioWaitNodeCancelledError, ScenarioWaitNodeValidationError, } from "./waitNodeExecutor.js";
|
|
@@ -110,19 +111,24 @@ const createInputSnapshot = (context) => ({
|
|
|
110
111
|
result: context.redisResult ?? null,
|
|
111
112
|
},
|
|
112
113
|
});
|
|
113
|
-
const createContextSnapshot = (context) =>
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
114
|
+
const createContextSnapshot = (context, mode = "full") => {
|
|
115
|
+
// "bounded": the payload-bearing slots are size-capped copies instead of
|
|
116
|
+
// references, so the event log never pins a node's full response body.
|
|
117
|
+
const bound = mode === "bounded" ? boundSnapshot : (value) => value;
|
|
118
|
+
return {
|
|
119
|
+
environment: { ...context.environment },
|
|
120
|
+
globals: { ...context.globals },
|
|
121
|
+
workflowContext: bound({ ...context.workflowContext }),
|
|
122
|
+
nodeMetaByLabel: cloneNodeMetaByLabel(context.nodeMetaByLabel),
|
|
123
|
+
workflowMeta: cloneWorkflowExecutionMeta(context.workflowMeta),
|
|
124
|
+
responseRoot: context.responseRoot ? bound({ ...context.responseRoot }) : null,
|
|
125
|
+
lastResponse: bound(context.lastResponse),
|
|
126
|
+
dbResult: bound(context.dbResult),
|
|
127
|
+
kafkaEvent: bound(context.kafkaEvent),
|
|
128
|
+
kafkaCapture: bound(context.kafkaCapture),
|
|
129
|
+
redisResult: bound(context.redisResult),
|
|
130
|
+
};
|
|
131
|
+
};
|
|
126
132
|
const buildKafkaEventValue = (message) => {
|
|
127
133
|
const fallbackValue = {
|
|
128
134
|
value: message.valueJson ?? message.valueText,
|
|
@@ -311,6 +317,7 @@ const createStepExecutionRecord = ({ stepId, stepType, title, }) => ({
|
|
|
311
317
|
errors: [],
|
|
312
318
|
durationMs: null,
|
|
313
319
|
statusCode: null,
|
|
320
|
+
statusExpectation: null,
|
|
314
321
|
errorMessage: null,
|
|
315
322
|
response: null,
|
|
316
323
|
testResults: [],
|
|
@@ -487,6 +494,7 @@ const updateRecordFromEvent = (records, event) => {
|
|
|
487
494
|
errors: event.errors ?? current.errors,
|
|
488
495
|
durationMs: event.durationMs ?? current.durationMs,
|
|
489
496
|
statusCode: event.statusCode ?? current.statusCode,
|
|
497
|
+
statusExpectation: event.statusExpectation ?? current.statusExpectation,
|
|
490
498
|
errorMessage: event.type === "step:fail"
|
|
491
499
|
? event.errorMessage
|
|
492
500
|
: current.errorMessage,
|
|
@@ -555,7 +563,7 @@ const callHandler = async (handlers, event) => {
|
|
|
555
563
|
return;
|
|
556
564
|
}
|
|
557
565
|
};
|
|
558
|
-
export const runScenario = async ({ scenario, environment = {}, globals = {}, runtimeAdapters, eventHandlers, signal, minNodeVisualStateMs = DEFAULT_MIN_NODE_VISUAL_STATE_MS, }) => {
|
|
566
|
+
export const runScenario = async ({ scenario, environment = {}, globals = {}, runtimeAdapters, eventHandlers, signal, minNodeVisualStateMs = DEFAULT_MIN_NODE_VISUAL_STATE_MS, eventContextMode = "full", }) => {
|
|
559
567
|
const runId = createRunId();
|
|
560
568
|
const startedAtMs = Date.now();
|
|
561
569
|
const startedAt = new Date(startedAtMs).toISOString();
|
|
@@ -566,6 +574,9 @@ export const runScenario = async ({ scenario, environment = {}, globals = {}, ru
|
|
|
566
574
|
const localStatuses = new Map(runtimeStepIds.map((stepId) => [stepId, "idle"]));
|
|
567
575
|
const records = new Map();
|
|
568
576
|
const events = [];
|
|
577
|
+
// Every emitted event carries a context snapshot; `runtimeContext` is
|
|
578
|
+
// assigned just below and is always initialised before the first emit.
|
|
579
|
+
const snapshotContext = () => createContextSnapshot(runtimeContext, eventContextMode);
|
|
569
580
|
const initialWorkflowMeta = createInitialWorkflowMeta({
|
|
570
581
|
startedAt,
|
|
571
582
|
totalNodes: runtimeStepIds.length,
|
|
@@ -861,6 +872,7 @@ export const runScenario = async ({ scenario, environment = {}, globals = {}, ru
|
|
|
861
872
|
const executionStartedAtMs = Date.now();
|
|
862
873
|
let inputData = createInputSnapshot(runtimeContext);
|
|
863
874
|
let statusCode = null;
|
|
875
|
+
let statusExpectation = null;
|
|
864
876
|
let response = null;
|
|
865
877
|
let outputData = null;
|
|
866
878
|
let testResults = [];
|
|
@@ -974,7 +986,7 @@ export const runScenario = async ({ scenario, environment = {}, globals = {}, ru
|
|
|
974
986
|
runId,
|
|
975
987
|
stepId,
|
|
976
988
|
node,
|
|
977
|
-
context:
|
|
989
|
+
context: snapshotContext(),
|
|
978
990
|
kafkaCapturePlans,
|
|
979
991
|
captureFromTimestampMs: startedAtMs,
|
|
980
992
|
signal,
|
|
@@ -988,6 +1000,7 @@ export const runScenario = async ({ scenario, environment = {}, globals = {}, ru
|
|
|
988
1000
|
runtimeContext.responseRoot = requestResult.responseRoot;
|
|
989
1001
|
response = requestResult.response;
|
|
990
1002
|
statusCode = requestResult.response.status;
|
|
1003
|
+
statusExpectation = requestResult.statusExpectation ?? null;
|
|
991
1004
|
outputData = requestResult.outputData;
|
|
992
1005
|
testResults = requestResult.testResults;
|
|
993
1006
|
contractResults = requestResult.contractResults;
|
|
@@ -1034,7 +1047,7 @@ export const runScenario = async ({ scenario, environment = {}, globals = {}, ru
|
|
|
1034
1047
|
},
|
|
1035
1048
|
}
|
|
1036
1049
|
: {}),
|
|
1037
|
-
context:
|
|
1050
|
+
context: snapshotContext(),
|
|
1038
1051
|
signal,
|
|
1039
1052
|
});
|
|
1040
1053
|
runtimeContext.dbResult = dbResult.dbResult;
|
|
@@ -1067,7 +1080,7 @@ export const runScenario = async ({ scenario, environment = {}, globals = {}, ru
|
|
|
1067
1080
|
runId,
|
|
1068
1081
|
stepId,
|
|
1069
1082
|
node,
|
|
1070
|
-
context:
|
|
1083
|
+
context: snapshotContext(),
|
|
1071
1084
|
signal,
|
|
1072
1085
|
});
|
|
1073
1086
|
scriptSource = scriptResult.scriptSource;
|
|
@@ -1091,7 +1104,7 @@ export const runScenario = async ({ scenario, environment = {}, globals = {}, ru
|
|
|
1091
1104
|
stepId,
|
|
1092
1105
|
node,
|
|
1093
1106
|
resolvedCommands,
|
|
1094
|
-
context:
|
|
1107
|
+
context: snapshotContext(),
|
|
1095
1108
|
signal,
|
|
1096
1109
|
});
|
|
1097
1110
|
runtimeContext.redisResult = redisResult.redisResult;
|
|
@@ -1143,7 +1156,7 @@ export const runScenario = async ({ scenario, environment = {}, globals = {}, ru
|
|
|
1143
1156
|
position: node.position,
|
|
1144
1157
|
data: { label: node.data.label, config: pollConfig.request },
|
|
1145
1158
|
},
|
|
1146
|
-
context:
|
|
1159
|
+
context: snapshotContext(),
|
|
1147
1160
|
kafkaCapturePlans: [],
|
|
1148
1161
|
captureFromTimestampMs: startedAtMs,
|
|
1149
1162
|
signal,
|
|
@@ -1157,6 +1170,7 @@ export const runScenario = async ({ scenario, environment = {}, globals = {}, ru
|
|
|
1157
1170
|
runtimeContext.responseRoot = tickResult.responseRoot;
|
|
1158
1171
|
response = tickResult.response;
|
|
1159
1172
|
statusCode = tickResult.response.status;
|
|
1173
|
+
statusExpectation = tickResult.statusExpectation ?? null;
|
|
1160
1174
|
testResults = tickResult.testResults;
|
|
1161
1175
|
contractResults = tickResult.contractResults;
|
|
1162
1176
|
contractSummary = tickResult.contractSummary;
|
|
@@ -1182,7 +1196,7 @@ export const runScenario = async ({ scenario, environment = {}, globals = {}, ru
|
|
|
1182
1196
|
},
|
|
1183
1197
|
resolvedQuery,
|
|
1184
1198
|
resolvedParams,
|
|
1185
|
-
context:
|
|
1199
|
+
context: snapshotContext(),
|
|
1186
1200
|
signal,
|
|
1187
1201
|
});
|
|
1188
1202
|
runtimeContext.dbResult = tickResult.dbResult;
|
|
@@ -1205,7 +1219,7 @@ export const runScenario = async ({ scenario, environment = {}, globals = {}, ru
|
|
|
1205
1219
|
data: { label: node.data.label, config: pollConfig.redis },
|
|
1206
1220
|
},
|
|
1207
1221
|
resolvedCommands,
|
|
1208
|
-
context:
|
|
1222
|
+
context: snapshotContext(),
|
|
1209
1223
|
signal,
|
|
1210
1224
|
});
|
|
1211
1225
|
runtimeContext.redisResult = tickResult.redisResult;
|
|
@@ -1223,7 +1237,7 @@ export const runScenario = async ({ scenario, environment = {}, globals = {}, ru
|
|
|
1223
1237
|
position: node.position,
|
|
1224
1238
|
data: { label: node.data.label, config: pollConfig.script },
|
|
1225
1239
|
},
|
|
1226
|
-
context:
|
|
1240
|
+
context: snapshotContext(),
|
|
1227
1241
|
signal,
|
|
1228
1242
|
});
|
|
1229
1243
|
scriptSource = tickResult.scriptSource;
|
|
@@ -1346,7 +1360,7 @@ export const runScenario = async ({ scenario, environment = {}, globals = {}, ru
|
|
|
1346
1360
|
runId,
|
|
1347
1361
|
stepId,
|
|
1348
1362
|
node,
|
|
1349
|
-
context:
|
|
1363
|
+
context: snapshotContext(),
|
|
1350
1364
|
deliveryRequest,
|
|
1351
1365
|
signal,
|
|
1352
1366
|
});
|
|
@@ -1642,7 +1656,7 @@ export const runScenario = async ({ scenario, environment = {}, globals = {}, ru
|
|
|
1642
1656
|
runId,
|
|
1643
1657
|
stepId,
|
|
1644
1658
|
node,
|
|
1645
|
-
context:
|
|
1659
|
+
context: snapshotContext(),
|
|
1646
1660
|
signal,
|
|
1647
1661
|
});
|
|
1648
1662
|
throwIfStopped(signal);
|
|
@@ -2212,6 +2226,7 @@ export const runScenario = async ({ scenario, environment = {}, globals = {}, ru
|
|
|
2212
2226
|
errorMessage: policyResult.finalErrorMessage ?? "Scenario node failed",
|
|
2213
2227
|
durationMs,
|
|
2214
2228
|
statusCode,
|
|
2229
|
+
statusExpectation,
|
|
2215
2230
|
response,
|
|
2216
2231
|
testResults,
|
|
2217
2232
|
contractResults,
|
|
@@ -2294,6 +2309,7 @@ export const runScenario = async ({ scenario, environment = {}, globals = {}, ru
|
|
|
2294
2309
|
"Scenario node failed but execution continued.",
|
|
2295
2310
|
durationMs,
|
|
2296
2311
|
statusCode,
|
|
2312
|
+
statusExpectation,
|
|
2297
2313
|
response,
|
|
2298
2314
|
testResults,
|
|
2299
2315
|
contractResults,
|
|
@@ -2371,6 +2387,7 @@ export const runScenario = async ({ scenario, environment = {}, globals = {}, ru
|
|
|
2371
2387
|
nodeMeta,
|
|
2372
2388
|
durationMs,
|
|
2373
2389
|
statusCode,
|
|
2390
|
+
statusExpectation,
|
|
2374
2391
|
response,
|
|
2375
2392
|
testResults,
|
|
2376
2393
|
contractResults,
|
|
@@ -2631,7 +2648,7 @@ export const runScenario = async ({ scenario, environment = {}, globals = {}, ru
|
|
|
2631
2648
|
durationMs: Date.now() - startedAtMs,
|
|
2632
2649
|
totalSteps: runtimeStepIds.length,
|
|
2633
2650
|
completedSteps: Array.from(localStatuses.values()).filter(isTerminalStatus).length,
|
|
2634
|
-
context:
|
|
2651
|
+
context: snapshotContext(),
|
|
2635
2652
|
workflowMeta: cloneWorkflowExecutionMeta(finalWorkflowMeta),
|
|
2636
2653
|
nodeExecutions: runtimeStepIds.map((stepId) => {
|
|
2637
2654
|
const descriptor = runtimeStepDescriptors.find((entry) => entry.stepId === stepId);
|