@testsmith/perfornium 0.1.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.
Files changed (164) hide show
  1. package/README.md +360 -0
  2. package/dist/cli/cli.d.ts +2 -0
  3. package/dist/cli/cli.js +192 -0
  4. package/dist/cli/commands/distributed.d.ts +11 -0
  5. package/dist/cli/commands/distributed.js +179 -0
  6. package/dist/cli/commands/import.d.ts +23 -0
  7. package/dist/cli/commands/import.js +461 -0
  8. package/dist/cli/commands/init.d.ts +7 -0
  9. package/dist/cli/commands/init.js +923 -0
  10. package/dist/cli/commands/mock.d.ts +7 -0
  11. package/dist/cli/commands/mock.js +281 -0
  12. package/dist/cli/commands/report.d.ts +5 -0
  13. package/dist/cli/commands/report.js +70 -0
  14. package/dist/cli/commands/run.d.ts +12 -0
  15. package/dist/cli/commands/run.js +260 -0
  16. package/dist/cli/commands/validate.d.ts +3 -0
  17. package/dist/cli/commands/validate.js +35 -0
  18. package/dist/cli/commands/worker.d.ts +27 -0
  19. package/dist/cli/commands/worker.js +320 -0
  20. package/dist/config/index.d.ts +2 -0
  21. package/dist/config/index.js +20 -0
  22. package/dist/config/parser.d.ts +19 -0
  23. package/dist/config/parser.js +330 -0
  24. package/dist/config/types/global-config.d.ts +74 -0
  25. package/dist/config/types/global-config.js +2 -0
  26. package/dist/config/types/hooks.d.ts +58 -0
  27. package/dist/config/types/hooks.js +3 -0
  28. package/dist/config/types/import-types.d.ts +33 -0
  29. package/dist/config/types/import-types.js +2 -0
  30. package/dist/config/types/index.d.ts +11 -0
  31. package/dist/config/types/index.js +27 -0
  32. package/dist/config/types/load-config.d.ts +32 -0
  33. package/dist/config/types/load-config.js +9 -0
  34. package/dist/config/types/output-config.d.ts +10 -0
  35. package/dist/config/types/output-config.js +2 -0
  36. package/dist/config/types/report-config.d.ts +10 -0
  37. package/dist/config/types/report-config.js +2 -0
  38. package/dist/config/types/runtime-types.d.ts +6 -0
  39. package/dist/config/types/runtime-types.js +2 -0
  40. package/dist/config/types/scenario-config.d.ts +30 -0
  41. package/dist/config/types/scenario-config.js +2 -0
  42. package/dist/config/types/step-types.d.ts +139 -0
  43. package/dist/config/types/step-types.js +2 -0
  44. package/dist/config/types/test-configuration.d.ts +18 -0
  45. package/dist/config/types/test-configuration.js +2 -0
  46. package/dist/config/types/worker-config.d.ts +12 -0
  47. package/dist/config/types/worker-config.js +2 -0
  48. package/dist/config/validator.d.ts +19 -0
  49. package/dist/config/validator.js +198 -0
  50. package/dist/core/csv-data-provider.d.ts +47 -0
  51. package/dist/core/csv-data-provider.js +265 -0
  52. package/dist/core/hooks-manager.d.ts +33 -0
  53. package/dist/core/hooks-manager.js +129 -0
  54. package/dist/core/index.d.ts +5 -0
  55. package/dist/core/index.js +11 -0
  56. package/dist/core/script-executor.d.ts +14 -0
  57. package/dist/core/script-executor.js +290 -0
  58. package/dist/core/step-executor.d.ts +41 -0
  59. package/dist/core/step-executor.js +680 -0
  60. package/dist/core/test-runner.d.ts +34 -0
  61. package/dist/core/test-runner.js +465 -0
  62. package/dist/core/threshold-evaluator.d.ts +43 -0
  63. package/dist/core/threshold-evaluator.js +170 -0
  64. package/dist/core/virtual-user-pool.d.ts +42 -0
  65. package/dist/core/virtual-user-pool.js +136 -0
  66. package/dist/core/virtual-user.d.ts +51 -0
  67. package/dist/core/virtual-user.js +488 -0
  68. package/dist/distributed/coordinator.d.ts +34 -0
  69. package/dist/distributed/coordinator.js +158 -0
  70. package/dist/distributed/health-monitor.d.ts +18 -0
  71. package/dist/distributed/health-monitor.js +72 -0
  72. package/dist/distributed/load-distributor.d.ts +17 -0
  73. package/dist/distributed/load-distributor.js +106 -0
  74. package/dist/distributed/remote-worker.d.ts +37 -0
  75. package/dist/distributed/remote-worker.js +241 -0
  76. package/dist/distributed/result-aggregator.d.ts +43 -0
  77. package/dist/distributed/result-aggregator.js +146 -0
  78. package/dist/dsl/index.d.ts +3 -0
  79. package/dist/dsl/index.js +11 -0
  80. package/dist/dsl/test-builder.d.ts +111 -0
  81. package/dist/dsl/test-builder.js +514 -0
  82. package/dist/importers/har-importer.d.ts +17 -0
  83. package/dist/importers/har-importer.js +172 -0
  84. package/dist/importers/open-api-importer.d.ts +23 -0
  85. package/dist/importers/open-api-importer.js +181 -0
  86. package/dist/importers/wsdl-importer.d.ts +42 -0
  87. package/dist/importers/wsdl-importer.js +440 -0
  88. package/dist/index.d.ts +5 -0
  89. package/dist/index.js +17 -0
  90. package/dist/load-patterns/arrivals.d.ts +7 -0
  91. package/dist/load-patterns/arrivals.js +118 -0
  92. package/dist/load-patterns/base.d.ts +9 -0
  93. package/dist/load-patterns/base.js +2 -0
  94. package/dist/load-patterns/basic.d.ts +7 -0
  95. package/dist/load-patterns/basic.js +117 -0
  96. package/dist/load-patterns/stepping.d.ts +6 -0
  97. package/dist/load-patterns/stepping.js +122 -0
  98. package/dist/metrics/collector.d.ts +72 -0
  99. package/dist/metrics/collector.js +662 -0
  100. package/dist/metrics/types.d.ts +135 -0
  101. package/dist/metrics/types.js +2 -0
  102. package/dist/outputs/base.d.ts +7 -0
  103. package/dist/outputs/base.js +2 -0
  104. package/dist/outputs/csv.d.ts +13 -0
  105. package/dist/outputs/csv.js +163 -0
  106. package/dist/outputs/graphite.d.ts +13 -0
  107. package/dist/outputs/graphite.js +126 -0
  108. package/dist/outputs/influxdb.d.ts +12 -0
  109. package/dist/outputs/influxdb.js +82 -0
  110. package/dist/outputs/json.d.ts +14 -0
  111. package/dist/outputs/json.js +107 -0
  112. package/dist/outputs/streaming-csv.d.ts +37 -0
  113. package/dist/outputs/streaming-csv.js +254 -0
  114. package/dist/outputs/streaming-json.d.ts +43 -0
  115. package/dist/outputs/streaming-json.js +353 -0
  116. package/dist/outputs/webhook.d.ts +16 -0
  117. package/dist/outputs/webhook.js +96 -0
  118. package/dist/protocols/base.d.ts +33 -0
  119. package/dist/protocols/base.js +2 -0
  120. package/dist/protocols/rest/handler.d.ts +67 -0
  121. package/dist/protocols/rest/handler.js +776 -0
  122. package/dist/protocols/soap/handler.d.ts +12 -0
  123. package/dist/protocols/soap/handler.js +165 -0
  124. package/dist/protocols/web/core-web-vitals.d.ts +121 -0
  125. package/dist/protocols/web/core-web-vitals.js +373 -0
  126. package/dist/protocols/web/handler.d.ts +50 -0
  127. package/dist/protocols/web/handler.js +706 -0
  128. package/dist/recorder/native-recorder.d.ts +14 -0
  129. package/dist/recorder/native-recorder.js +533 -0
  130. package/dist/recorder/scenario-recorder.d.ts +55 -0
  131. package/dist/recorder/scenario-recorder.js +296 -0
  132. package/dist/reporting/constants.d.ts +94 -0
  133. package/dist/reporting/constants.js +82 -0
  134. package/dist/reporting/enhanced-html-generator.d.ts +55 -0
  135. package/dist/reporting/enhanced-html-generator.js +965 -0
  136. package/dist/reporting/generator.d.ts +42 -0
  137. package/dist/reporting/generator.js +1217 -0
  138. package/dist/reporting/statistics.d.ts +144 -0
  139. package/dist/reporting/statistics.js +742 -0
  140. package/dist/reporting/templates/enhanced-report.hbs +2812 -0
  141. package/dist/reporting/templates/html.hbs +2453 -0
  142. package/dist/utils/faker-manager.d.ts +55 -0
  143. package/dist/utils/faker-manager.js +166 -0
  144. package/dist/utils/file-manager.d.ts +33 -0
  145. package/dist/utils/file-manager.js +154 -0
  146. package/dist/utils/handlebars-manager.d.ts +42 -0
  147. package/dist/utils/handlebars-manager.js +172 -0
  148. package/dist/utils/logger.d.ts +16 -0
  149. package/dist/utils/logger.js +46 -0
  150. package/dist/utils/template.d.ts +80 -0
  151. package/dist/utils/template.js +513 -0
  152. package/dist/utils/test-output-writer.d.ts +56 -0
  153. package/dist/utils/test-output-writer.js +643 -0
  154. package/dist/utils/time.d.ts +3 -0
  155. package/dist/utils/time.js +23 -0
  156. package/dist/utils/timestamp-helper.d.ts +17 -0
  157. package/dist/utils/timestamp-helper.js +53 -0
  158. package/dist/workers/manager.d.ts +18 -0
  159. package/dist/workers/manager.js +95 -0
  160. package/dist/workers/server.d.ts +21 -0
  161. package/dist/workers/server.js +205 -0
  162. package/dist/workers/worker.d.ts +19 -0
  163. package/dist/workers/worker.js +147 -0
  164. package/package.json +102 -0
@@ -0,0 +1,265 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.CSVDataProvider = void 0;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const papaparse_1 = __importDefault(require("papaparse"));
43
+ const logger_1 = require("../utils/logger");
44
+ /** Apply variable name mapping to a row */
45
+ function applyVariableMapping(row, mapping) {
46
+ if (!mapping || Object.keys(mapping).length === 0) {
47
+ return row;
48
+ }
49
+ const mappedRow = {};
50
+ for (const [csvColumn, value] of Object.entries(row)) {
51
+ // Use mapped name if defined, otherwise keep original column name
52
+ const variableName = mapping[csvColumn] || csvColumn;
53
+ mappedRow[variableName] = value;
54
+ }
55
+ return mappedRow;
56
+ }
57
+ class CSVDataProvider {
58
+ // Remove test termination callback - we don't need it anymore
59
+ constructor(filePath, config) {
60
+ this.data = [];
61
+ this.originalData = [];
62
+ this.currentIndex = 0;
63
+ this.isLoaded = false;
64
+ this.isExhausted = false;
65
+ this.globalIndex = 0; // For sequential tracking across all modes
66
+ this.accessCount = 0; // For random mode tracking
67
+ this.filePath = filePath;
68
+ this.config = config;
69
+ }
70
+ static getInstance(config) {
71
+ const fullPath = path.resolve(CSVDataProvider.baseDir, config.file);
72
+ const key = `${fullPath}-${JSON.stringify(config)}`;
73
+ if (!CSVDataProvider.instances.has(key)) {
74
+ CSVDataProvider.instances.set(key, new CSVDataProvider(fullPath, config));
75
+ }
76
+ return CSVDataProvider.instances.get(key);
77
+ }
78
+ static setBaseDir(dir) {
79
+ CSVDataProvider.baseDir = dir;
80
+ }
81
+ // ... existing loadData method stays the same ...
82
+ async loadData() {
83
+ if (this.isLoaded) {
84
+ return;
85
+ }
86
+ const fullPath = path.resolve(CSVDataProvider.baseDir, this.config.file);
87
+ if (!fs.existsSync(fullPath)) {
88
+ throw new Error(`CSV file not found: ${fullPath}`);
89
+ }
90
+ logger_1.logger.info(`📊 Loading CSV data from: ${this.config.file}`);
91
+ const encoding = this.config.encoding || 'utf8';
92
+ const csvContent = fs.readFileSync(fullPath, encoding);
93
+ const parseConfig = {
94
+ header: true,
95
+ delimiter: this.config.delimiter || ',',
96
+ skipEmptyLines: this.config.skipEmptyLines !== false,
97
+ dynamicTyping: true,
98
+ delimitersToGuess: [',', '\t', '|', ';']
99
+ };
100
+ const parseResult = papaparse_1.default.parse(csvContent, parseConfig);
101
+ if (parseResult.errors.length > 0) {
102
+ logger_1.logger.warn('CSV parsing warnings:', parseResult.errors);
103
+ }
104
+ this.originalData = parseResult.data;
105
+ if (this.config.skipFirstLine) {
106
+ this.originalData = this.originalData.slice(1);
107
+ }
108
+ if (this.config.columns && this.config.columns.length > 0) {
109
+ this.originalData = this.originalData.map(row => {
110
+ const filteredRow = {};
111
+ for (const col of this.config.columns) {
112
+ if (row.hasOwnProperty(col)) {
113
+ filteredRow[col] = row[col];
114
+ }
115
+ }
116
+ return filteredRow;
117
+ });
118
+ }
119
+ if (this.config.filter) {
120
+ this.originalData = this.filterData(this.originalData, this.config.filter);
121
+ }
122
+ if (this.config.randomize) {
123
+ this.originalData = this.shuffleArray([...this.originalData]);
124
+ }
125
+ this.data = [...this.originalData];
126
+ this.isLoaded = true;
127
+ logger_1.logger.info(`📊 Loaded ${this.data.length} rows from CSV: ${this.config.file}`);
128
+ }
129
+ /**
130
+ * Enhanced getNextRow - returns null when exhausted if cycleOnExhaustion is false
131
+ */
132
+ async getNextRow(vuId) {
133
+ await this.loadData();
134
+ if (this.originalData.length === 0) {
135
+ logger_1.logger.warn(`📊 No data available in CSV: ${this.config.file}`);
136
+ return null;
137
+ }
138
+ // If cycling is disabled, use sequential exhaustible access
139
+ if (this.config.cycleOnExhaustion === false) {
140
+ if (this.globalIndex >= this.originalData.length) {
141
+ logger_1.logger.warn(`📊 VU${vuId}: CSV data exhausted in file: ${this.config.file} (next mode, cycling disabled)`);
142
+ return null; // Just return null, don't terminate test
143
+ }
144
+ const row = this.originalData[this.globalIndex];
145
+ this.globalIndex++;
146
+ logger_1.logger.info(`📊 VU${vuId} using sequential CSV row ${this.globalIndex}/${this.originalData.length}:`, Object.keys(row));
147
+ return applyVariableMapping({ ...row }, this.config.variables);
148
+ }
149
+ else {
150
+ // Normal round-robin behavior
151
+ const index = (vuId - 1) % this.originalData.length;
152
+ const row = this.originalData[index];
153
+ logger_1.logger.debug(`📊 VU${vuId} using CSV row ${index + 1}/${this.originalData.length}:`, Object.keys(row));
154
+ return applyVariableMapping({ ...row }, this.config.variables);
155
+ }
156
+ }
157
+ /**
158
+ * Enhanced getUniqueRow - returns null when exhausted if cycleOnExhaustion is false
159
+ */
160
+ async getUniqueRow(vuId) {
161
+ await this.loadData();
162
+ if (this.data.length === 0) {
163
+ if (this.isExhausted && this.config.cycleOnExhaustion === false) {
164
+ logger_1.logger.warn(`📊 VU${vuId}: CSV data exhausted and cycling disabled: ${this.config.file}`);
165
+ return null; // Just return null, don't terminate test
166
+ }
167
+ logger_1.logger.warn(`📊 VU${vuId}: No more data available in CSV: ${this.config.file}`);
168
+ return null;
169
+ }
170
+ const row = this.data.shift();
171
+ logger_1.logger.info(`📊 VU${vuId} using unique CSV row (${this.data.length} remaining):`, Object.keys(row));
172
+ if (this.data.length === 0) {
173
+ this.isExhausted = true;
174
+ if (this.config.cycleOnExhaustion !== false) {
175
+ logger_1.logger.info(`📊 CSV data exhausted, reloading: ${this.config.file}`);
176
+ this.data = [...this.originalData];
177
+ if (this.config.randomize) {
178
+ this.data = this.shuffleArray(this.data);
179
+ }
180
+ this.isExhausted = false;
181
+ logger_1.logger.info(`📊 CSV data reloaded: ${this.data.length} rows available`);
182
+ }
183
+ else {
184
+ logger_1.logger.warn(`📊 CSV data exhausted, cycling disabled: ${this.config.file} - future requests will return null`);
185
+ }
186
+ }
187
+ return applyVariableMapping({ ...row }, this.config.variables);
188
+ }
189
+ /**
190
+ * Enhanced getRandomRow - returns null when exhausted if cycleOnExhaustion is false
191
+ */
192
+ async getRandomRow(vuId = 0) {
193
+ await this.loadData();
194
+ if (this.originalData.length === 0) {
195
+ logger_1.logger.warn(`📊 No data available for random selection in CSV: ${this.config.file}`);
196
+ return null;
197
+ }
198
+ // If cycling is disabled, track accesses and stop after using all data once
199
+ if (this.config.cycleOnExhaustion === false) {
200
+ this.accessCount++;
201
+ if (this.accessCount > this.originalData.length) {
202
+ logger_1.logger.warn(`📊 VU${vuId}: CSV data exhausted in file: ${this.config.file} (random mode, cycling disabled, ${this.accessCount} accesses)`);
203
+ return null; // Just return null, don't terminate test
204
+ }
205
+ }
206
+ const randomIndex = Math.floor(Math.random() * this.originalData.length);
207
+ const row = this.originalData[randomIndex];
208
+ logger_1.logger.debug(`📊 VU${vuId} using random CSV row ${randomIndex + 1}/${this.originalData.length} (access ${this.accessCount}):`, Object.keys(row));
209
+ return applyVariableMapping({ ...row }, this.config.variables);
210
+ }
211
+ filterData(data, filterExpression) {
212
+ try {
213
+ const operators = ['!=', '>=', '<=', '=', '>', '<'];
214
+ let operator = '';
215
+ let parts = [];
216
+ for (const op of operators) {
217
+ if (filterExpression.includes(op)) {
218
+ operator = op;
219
+ parts = filterExpression.split(op).map(p => p.trim());
220
+ break;
221
+ }
222
+ }
223
+ if (parts.length !== 2) {
224
+ logger_1.logger.warn(`Invalid filter expression: ${filterExpression}`);
225
+ return data;
226
+ }
227
+ const [column, value] = parts;
228
+ const filterValue = isNaN(Number(value)) ? value.replace(/['"]/g, '') : Number(value);
229
+ return data.filter(row => {
230
+ const rowValue = row[column];
231
+ switch (operator) {
232
+ case '=':
233
+ return rowValue == filterValue;
234
+ case '!=':
235
+ return rowValue != filterValue;
236
+ case '>':
237
+ return Number(rowValue) > Number(filterValue);
238
+ case '<':
239
+ return Number(rowValue) < Number(filterValue);
240
+ case '>=':
241
+ return Number(rowValue) >= Number(filterValue);
242
+ case '<=':
243
+ return Number(rowValue) <= Number(filterValue);
244
+ default:
245
+ return true;
246
+ }
247
+ });
248
+ }
249
+ catch (error) {
250
+ logger_1.logger.warn(`Error applying filter "${filterExpression}":`, error);
251
+ return data;
252
+ }
253
+ }
254
+ shuffleArray(array) {
255
+ const shuffled = [...array];
256
+ for (let i = shuffled.length - 1; i > 0; i--) {
257
+ const j = Math.floor(Math.random() * (i + 1));
258
+ [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
259
+ }
260
+ return shuffled;
261
+ }
262
+ }
263
+ exports.CSVDataProvider = CSVDataProvider;
264
+ CSVDataProvider.instances = new Map();
265
+ CSVDataProvider.baseDir = process.cwd();
@@ -0,0 +1,33 @@
1
+ import { VUHooks, ScenarioHooks, LoopHooks, StepHooks, ScriptResult } from '../config/types/hooks';
2
+ export declare class VUHooksManager {
3
+ private vuHooks?;
4
+ private vuId;
5
+ private testName;
6
+ constructor(testName: string, vuId: number, vuHooks?: VUHooks);
7
+ executeBeforeVU(variables: Record<string, any>, extractedData: Record<string, any>): Promise<ScriptResult | null>;
8
+ executeTeardownVU(variables: Record<string, any>, extractedData: Record<string, any>): Promise<ScriptResult | null>;
9
+ }
10
+ export declare class ScenarioHooksManager {
11
+ private scenarioHooks?;
12
+ private vuId;
13
+ private testName;
14
+ private scenarioName;
15
+ private scenarioStartTime;
16
+ constructor(testName: string, vuId: number, scenarioName: string, hooks?: ScenarioHooks & LoopHooks);
17
+ executeBeforeScenario(variables: Record<string, any>, extractedData: Record<string, any>, csvData?: Record<string, any>): Promise<ScriptResult | null>;
18
+ executeTeardownScenario(variables: Record<string, any>, extractedData: Record<string, any>, csvData?: Record<string, any>): Promise<ScriptResult | null>;
19
+ executeBeforeLoop(loopIteration: number, variables: Record<string, any>, extractedData: Record<string, any>, csvData?: Record<string, any>): Promise<ScriptResult | null>;
20
+ executeAfterLoop(loopIteration: number, variables: Record<string, any>, extractedData: Record<string, any>, csvData?: Record<string, any>): Promise<ScriptResult | null>;
21
+ }
22
+ export declare class StepHooksManager {
23
+ private stepHooks?;
24
+ private vuId;
25
+ private testName;
26
+ private scenarioName;
27
+ private stepName;
28
+ private stepType;
29
+ constructor(testName: string, vuId: number, scenarioName: string, stepName: string, stepType: string, hooks?: StepHooks);
30
+ executeBeforeStep(variables: Record<string, any>, extractedData: Record<string, any>, csvData?: Record<string, any>): Promise<ScriptResult | null>;
31
+ executeOnStepError(error: Error, variables: Record<string, any>, extractedData: Record<string, any>, csvData?: Record<string, any>): Promise<ScriptResult | null>;
32
+ executeTeardownStep(variables: Record<string, any>, extractedData: Record<string, any>, csvData?: Record<string, any>, stepResult?: any): Promise<ScriptResult | null>;
33
+ }
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StepHooksManager = exports.ScenarioHooksManager = exports.VUHooksManager = void 0;
4
+ const script_executor_1 = require("./script-executor");
5
+ const logger_1 = require("../utils/logger");
6
+ class VUHooksManager {
7
+ constructor(testName, vuId, vuHooks) {
8
+ this.testName = testName;
9
+ this.vuId = vuId;
10
+ this.vuHooks = vuHooks;
11
+ }
12
+ async executeBeforeVU(variables, extractedData) {
13
+ if (!this.vuHooks?.beforeVU)
14
+ return null;
15
+ const context = script_executor_1.ScriptExecutor.createContext(this.testName, this.vuId, variables, extractedData);
16
+ return await script_executor_1.ScriptExecutor.executeHookScript(this.vuHooks.beforeVU, context, 'beforeVU');
17
+ }
18
+ async executeTeardownVU(variables, extractedData) {
19
+ if (!this.vuHooks?.teardownVU)
20
+ return null;
21
+ const context = script_executor_1.ScriptExecutor.createContext(this.testName, this.vuId, variables, extractedData);
22
+ return await script_executor_1.ScriptExecutor.executeHookScript(this.vuHooks.teardownVU, context, 'teardownVU');
23
+ }
24
+ }
25
+ exports.VUHooksManager = VUHooksManager;
26
+ class ScenarioHooksManager {
27
+ constructor(testName, vuId, scenarioName, hooks) {
28
+ this.scenarioStartTime = 0;
29
+ this.testName = testName;
30
+ this.vuId = vuId;
31
+ this.scenarioName = scenarioName;
32
+ this.scenarioHooks = hooks;
33
+ }
34
+ async executeBeforeScenario(variables, extractedData, csvData) {
35
+ if (!this.scenarioHooks?.beforeScenario)
36
+ return null;
37
+ this.scenarioStartTime = Date.now();
38
+ const context = script_executor_1.ScriptExecutor.createContext(this.testName, this.vuId, variables, extractedData, csvData, {
39
+ scenario_name: this.scenarioName,
40
+ scenario_start_time: this.scenarioStartTime
41
+ });
42
+ const result = await script_executor_1.ScriptExecutor.executeHookScript(this.scenarioHooks.beforeScenario, context, 'beforeScenario');
43
+ // CRITICAL FIX: Merge both returned variables AND the context's extracted_data
44
+ if (result?.success) {
45
+ // Merge variables returned from the hook
46
+ if (result.variables) {
47
+ Object.assign(variables, result.variables);
48
+ }
49
+ // IMPORTANT: Also merge the context's extracted_data back into the main extracted_data
50
+ Object.assign(extractedData, context.extracted_data);
51
+ logger_1.logger.debug(`VU${this.vuId}: beforeScenario extracted data: ${Object.keys(context.extracted_data).join(', ')}`);
52
+ logger_1.logger.debug(`VU${this.vuId}: beforeScenario extracted values: ${JSON.stringify(context.extracted_data)}`);
53
+ }
54
+ return result;
55
+ }
56
+ async executeTeardownScenario(variables, extractedData, csvData) {
57
+ if (!this.scenarioHooks?.teardownScenario)
58
+ return null;
59
+ const context = script_executor_1.ScriptExecutor.createContext(this.testName, this.vuId, variables, extractedData, csvData, {
60
+ scenario_name: this.scenarioName,
61
+ scenario_start_time: this.scenarioStartTime
62
+ });
63
+ return await script_executor_1.ScriptExecutor.executeHookScript(this.scenarioHooks.teardownScenario, context, 'teardownScenario');
64
+ }
65
+ async executeBeforeLoop(loopIteration, variables, extractedData, csvData) {
66
+ if (!this.scenarioHooks?.beforeLoop)
67
+ return null;
68
+ const context = script_executor_1.ScriptExecutor.createContext(this.testName, this.vuId, variables, extractedData, csvData, {
69
+ scenario_name: this.scenarioName,
70
+ loop_iteration: loopIteration,
71
+ loop_start_time: Date.now()
72
+ });
73
+ return await script_executor_1.ScriptExecutor.executeHookScript(this.scenarioHooks.beforeLoop, context, 'beforeLoop');
74
+ }
75
+ async executeAfterLoop(loopIteration, variables, extractedData, csvData) {
76
+ if (!this.scenarioHooks?.afterLoop)
77
+ return null;
78
+ const context = script_executor_1.ScriptExecutor.createContext(this.testName, this.vuId, variables, extractedData, csvData, {
79
+ scenario_name: this.scenarioName,
80
+ loop_iteration: loopIteration
81
+ });
82
+ return await script_executor_1.ScriptExecutor.executeHookScript(this.scenarioHooks.afterLoop, context, 'afterLoop');
83
+ }
84
+ }
85
+ exports.ScenarioHooksManager = ScenarioHooksManager;
86
+ class StepHooksManager {
87
+ constructor(testName, vuId, scenarioName, stepName, stepType, hooks) {
88
+ this.testName = testName;
89
+ this.vuId = vuId;
90
+ this.scenarioName = scenarioName;
91
+ this.stepName = stepName;
92
+ this.stepType = stepType;
93
+ this.stepHooks = hooks;
94
+ }
95
+ async executeBeforeStep(variables, extractedData, csvData) {
96
+ if (!this.stepHooks?.beforeStep)
97
+ return null;
98
+ const context = script_executor_1.ScriptExecutor.createContext(this.testName, this.vuId, variables, extractedData, csvData, {
99
+ scenario_name: this.scenarioName,
100
+ step_name: this.stepName,
101
+ step_type: this.stepType,
102
+ step_start_time: Date.now()
103
+ });
104
+ return await script_executor_1.ScriptExecutor.executeHookScript(this.stepHooks.beforeStep, context, 'beforeStep');
105
+ }
106
+ async executeOnStepError(error, variables, extractedData, csvData) {
107
+ if (!this.stepHooks?.onStepError)
108
+ return null;
109
+ const context = script_executor_1.ScriptExecutor.createContext(this.testName, this.vuId, variables, extractedData, csvData, {
110
+ scenario_name: this.scenarioName,
111
+ step_name: this.stepName,
112
+ step_type: this.stepType,
113
+ error
114
+ });
115
+ return await script_executor_1.ScriptExecutor.executeHookScript(this.stepHooks.onStepError, context, 'onStepError');
116
+ }
117
+ async executeTeardownStep(variables, extractedData, csvData, stepResult) {
118
+ if (!this.stepHooks?.teardownStep)
119
+ return null;
120
+ const context = script_executor_1.ScriptExecutor.createContext(this.testName, this.vuId, variables, extractedData, csvData, {
121
+ scenario_name: this.scenarioName,
122
+ step_name: this.stepName,
123
+ step_type: this.stepType,
124
+ last_step_result: stepResult
125
+ });
126
+ return await script_executor_1.ScriptExecutor.executeHookScript(this.stepHooks.teardownStep, context, 'teardownStep');
127
+ }
128
+ }
129
+ exports.StepHooksManager = StepHooksManager;
@@ -0,0 +1,5 @@
1
+ export { TestRunner } from './test-runner';
2
+ export { VirtualUser } from './virtual-user';
3
+ export { StepExecutor } from './step-executor';
4
+ export { CSVDataProvider } from './csv-data-provider';
5
+ export type { CSVDataRow } from './csv-data-provider';
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CSVDataProvider = exports.StepExecutor = exports.VirtualUser = exports.TestRunner = void 0;
4
+ var test_runner_1 = require("./test-runner");
5
+ Object.defineProperty(exports, "TestRunner", { enumerable: true, get: function () { return test_runner_1.TestRunner; } });
6
+ var virtual_user_1 = require("./virtual-user");
7
+ Object.defineProperty(exports, "VirtualUser", { enumerable: true, get: function () { return virtual_user_1.VirtualUser; } });
8
+ var step_executor_1 = require("./step-executor");
9
+ Object.defineProperty(exports, "StepExecutor", { enumerable: true, get: function () { return step_executor_1.StepExecutor; } });
10
+ var csv_data_provider_1 = require("./csv-data-provider");
11
+ Object.defineProperty(exports, "CSVDataProvider", { enumerable: true, get: function () { return csv_data_provider_1.CSVDataProvider; } });
@@ -0,0 +1,14 @@
1
+ import { HookScript, ScriptContext, ScriptResult } from '../config/types/hooks';
2
+ export declare class ScriptExecutor {
3
+ private static baseDir;
4
+ private static scriptCache;
5
+ private static stepExecutor?;
6
+ static setStepExecutor(stepExecutor: any): void;
7
+ static createContext(testName: string, vuId: number, variables: Record<string, any>, extractedData: Record<string, any>, csvData?: Record<string, any>, additionalContext?: Partial<ScriptContext>): ScriptContext;
8
+ static executeHookScript(script: HookScript, context: ScriptContext, hookName: string): Promise<ScriptResult>;
9
+ private static executeInlineScript;
10
+ private static executeFileScript;
11
+ private static executeStepsScript;
12
+ private static transpileTypeScript;
13
+ static clearCache(): void;
14
+ }