@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,330 @@
1
+ "use strict";
2
+ // Updated ConfigParser to support both YAML and TypeScript
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.ConfigParser = void 0;
38
+ const YAML = __importStar(require("yaml"));
39
+ const fs = __importStar(require("fs"));
40
+ const path = __importStar(require("path"));
41
+ const template_1 = require("../utils/template");
42
+ const core_1 = require("../core");
43
+ const logger_1 = require("../utils/logger");
44
+ class ConfigParser {
45
+ constructor() {
46
+ this.templateProcessor = new template_1.TemplateProcessor();
47
+ }
48
+ async parse(configPath, environment) {
49
+ logger_1.logger.debug(`ConfigParser.parse called with: ${configPath}, ${environment}`);
50
+ if (!fs.existsSync(configPath)) {
51
+ throw new Error(`Configuration file not found: ${configPath}`);
52
+ }
53
+ let config;
54
+ // Determine file type and parse accordingly
55
+ const ext = path.extname(configPath).toLowerCase();
56
+ if (ext === '.ts' || ext === '.js') {
57
+ // Handle TypeScript/JavaScript files
58
+ config = await this.parseTypeScript(configPath);
59
+ }
60
+ else {
61
+ // Handle YAML/JSON files
62
+ const configContent = fs.readFileSync(configPath, 'utf8');
63
+ config = this.parseContent(configContent);
64
+ }
65
+ logger_1.logger.debug(`Parsed config.global: ${JSON.stringify(config.global, null, 2)}`);
66
+ // Setup faker configuration if specified
67
+ logger_1.logger.debug('About to setup faker...');
68
+ this.setupFaker(config);
69
+ logger_1.logger.debug('Faker setup completed');
70
+ // Setup base directories for CSV and templates if needed
71
+ this.setupBaseDirectories(config, configPath);
72
+ // Validate required fields (now includes CSV validation)
73
+ this.validateRequiredFields(config);
74
+ if (environment) {
75
+ const envConfig = await this.loadEnvironmentConfig(environment, path.dirname(configPath));
76
+ return this.mergeConfigs(config, envConfig);
77
+ }
78
+ return config;
79
+ }
80
+ async parseTypeScript(configPath) {
81
+ try {
82
+ // Resolve to absolute path
83
+ const absolutePath = path.resolve(configPath);
84
+ // Check if file exists
85
+ if (!fs.existsSync(absolutePath)) {
86
+ throw new Error(`Configuration file not found: ${absolutePath}`);
87
+ }
88
+ let module;
89
+ if (absolutePath.endsWith('.ts')) {
90
+ // For TypeScript files, we need proper transpilation support
91
+ try {
92
+ // Try to use ts-node/register for TypeScript support
93
+ require('ts-node/register');
94
+ }
95
+ catch {
96
+ // If ts-node is not globally available, try to use it from local node_modules
97
+ try {
98
+ const tsNodePath = require.resolve('ts-node/register', { paths: [process.cwd()] });
99
+ require(tsNodePath);
100
+ }
101
+ catch {
102
+ // If ts-node still not found, provide helpful error
103
+ logger_1.logger.warn('ts-node not found. Installing it will enable TypeScript imports.');
104
+ logger_1.logger.warn('Install with: npm install --save-dev ts-node typescript');
105
+ logger_1.logger.warn('Attempting to run as plain JavaScript...');
106
+ }
107
+ }
108
+ // Clear require cache
109
+ if (require.cache[absolutePath]) {
110
+ delete require.cache[absolutePath];
111
+ }
112
+ try {
113
+ // Try to require the file
114
+ module = require(absolutePath);
115
+ }
116
+ catch (error) {
117
+ // If it fails with import/export errors, try alternative approaches
118
+ if (error.message.includes('Cannot use import statement') ||
119
+ error.message.includes('Unexpected token')) {
120
+ // Check if this is a plain config file (no imports) or a DSL file (with imports)
121
+ const fileContent = fs.readFileSync(absolutePath, 'utf8');
122
+ const hasImports = fileContent.includes('import ') || fileContent.includes('export ');
123
+ if (hasImports) {
124
+ // This is a DSL file with imports - it needs ts-node
125
+ throw new Error('TypeScript file contains imports and requires ts-node for execution.\n' +
126
+ 'Please install it:\n' +
127
+ ' npm install --save-dev ts-node typescript\n' +
128
+ 'Or globally:\n' +
129
+ ' npm install -g ts-node typescript\n\n' +
130
+ 'Then run your test again.');
131
+ }
132
+ else {
133
+ // This is a plain config file - we can evaluate it
134
+ module = this.evaluatePlainTypeScript(fileContent, absolutePath);
135
+ }
136
+ }
137
+ else {
138
+ throw error;
139
+ }
140
+ }
141
+ }
142
+ else {
143
+ // Regular JavaScript file
144
+ module = require(absolutePath);
145
+ }
146
+ // Handle different export styles
147
+ let config;
148
+ if (module && module.default) {
149
+ config = module.default;
150
+ }
151
+ else if (module && module.config) {
152
+ config = module.config;
153
+ }
154
+ else if (typeof module === 'object' && module.name) {
155
+ config = module;
156
+ }
157
+ else {
158
+ throw new Error('File must export a TestConfiguration object as default or named "config"');
159
+ }
160
+ // If it's a builder or has a build method, build it
161
+ if (typeof config === 'object' && 'build' in config && typeof config.build === 'function') {
162
+ config = config.build();
163
+ }
164
+ return config;
165
+ }
166
+ catch (error) {
167
+ // Improve error messages
168
+ if (error.code === 'MODULE_NOT_FOUND' && error.message.includes('perfornium')) {
169
+ throw new Error('Cannot find perfornium modules. Make sure you are importing from the correct path:\n' +
170
+ ' import { test } from "perfornium/dsl";\n' +
171
+ 'Or if running from source:\n' +
172
+ ' import { test } from "./src/dsl";\n\n' +
173
+ 'Original error: ' + error.message);
174
+ }
175
+ throw new Error(`Failed to load configuration: ${error.message}`);
176
+ }
177
+ }
178
+ evaluatePlainTypeScript(fileContent, absolutePath) {
179
+ // Create a module context for plain TypeScript files without imports
180
+ const moduleContext = {
181
+ exports: {},
182
+ require: require,
183
+ module: { exports: {} },
184
+ __filename: absolutePath,
185
+ __dirname: path.dirname(absolutePath),
186
+ process: process,
187
+ console: console
188
+ };
189
+ try {
190
+ // Wrap in a function and execute
191
+ const fn = new Function('exports', 'require', 'module', '__filename', '__dirname', 'process', 'console', fileContent);
192
+ fn(moduleContext.exports, moduleContext.require, moduleContext.module, moduleContext.__filename, moduleContext.__dirname, moduleContext.process, moduleContext.console);
193
+ return moduleContext.module.exports || moduleContext.exports;
194
+ }
195
+ catch (error) {
196
+ throw new Error(`Failed to evaluate TypeScript file: ${error.message}`);
197
+ }
198
+ }
199
+ // Rest of your existing methods remain the same...
200
+ setupBaseDirectories(config, configPath) {
201
+ let baseDir = path.dirname(configPath);
202
+ // Walk up directories to find templates folder
203
+ let currentDir = baseDir;
204
+ while (currentDir !== path.dirname(currentDir)) {
205
+ if (fs.existsSync(path.join(currentDir, 'templates'))) {
206
+ baseDir = currentDir;
207
+ break;
208
+ }
209
+ currentDir = path.dirname(currentDir);
210
+ }
211
+ const hasCSVScenarios = config.scenarios?.some((s) => s.csv_data);
212
+ const configStr = JSON.stringify(config);
213
+ const hasTemplates = configStr.includes('{{template:') || configStr.includes('{{csv:');
214
+ if (hasCSVScenarios || hasTemplates) {
215
+ core_1.CSVDataProvider.setBaseDir(baseDir);
216
+ template_1.TemplateProcessor.setBaseDir(baseDir);
217
+ logger_1.logger.debug(`Set base directory for CSV/templates: ${baseDir}`);
218
+ }
219
+ }
220
+ setupFaker(config) {
221
+ logger_1.logger.debug('ConfigParser.setupFaker called');
222
+ logger_1.logger.debug(`config.global: ${JSON.stringify(config.global, null, 2)}`);
223
+ if (config.global?.faker) {
224
+ logger_1.logger.debug(`Found faker config: ${JSON.stringify(config.global.faker)}`);
225
+ logger_1.logger.debug('About to call configureFaker...');
226
+ this.templateProcessor.configureFaker(config.global.faker);
227
+ logger_1.logger.debug('configureFaker call completed');
228
+ }
229
+ else {
230
+ logger_1.logger.debug('No faker config found in global');
231
+ }
232
+ }
233
+ parseContent(content) {
234
+ const trimmed = content.trim();
235
+ if (trimmed.startsWith('{')) {
236
+ return JSON.parse(content);
237
+ }
238
+ else {
239
+ return YAML.parse(content);
240
+ }
241
+ }
242
+ validateRequiredFields(config) {
243
+ const requiredFields = ['name', 'load', 'scenarios'];
244
+ for (const field of requiredFields) {
245
+ if (!config[field]) {
246
+ throw new Error(`Required field missing: ${field}`);
247
+ }
248
+ }
249
+ if (!config.scenarios || config.scenarios.length === 0) {
250
+ throw new Error('At least one scenario must be defined');
251
+ }
252
+ // Validate CSV configurations in scenarios
253
+ for (const scenario of config.scenarios) {
254
+ if (scenario.csv_data) {
255
+ this.validateCSVConfig(scenario.csv_data, scenario.name);
256
+ }
257
+ }
258
+ if (config.global?.faker?.locale) {
259
+ const supportedLocales = this.templateProcessor.getAvailableLocales();
260
+ if (!supportedLocales.includes(config.global.faker.locale)) {
261
+ throw new Error(`Unsupported faker locale: ${config.global.faker.locale}. Supported locales: ${supportedLocales.join(', ')}`);
262
+ }
263
+ }
264
+ }
265
+ validateCSVConfig(csvConfig, scenarioName) {
266
+ if (!csvConfig.file) {
267
+ throw new Error(`CSV configuration missing 'file' property in scenario: ${scenarioName}`);
268
+ }
269
+ // Validate csv_mode if specified
270
+ const validModes = ['next', 'unique', 'random'];
271
+ if (csvConfig.mode && !validModes.includes(csvConfig.mode)) {
272
+ throw new Error(`Invalid csv_mode '${csvConfig.mode}' in scenario ${scenarioName}. Valid modes: ${validModes.join(', ')}`);
273
+ }
274
+ // Validate encoding if specified
275
+ const validEncodings = ['utf8', 'utf-8', 'ascii', 'latin1', 'base64', 'hex'];
276
+ if (csvConfig.encoding && !validEncodings.includes(csvConfig.encoding)) {
277
+ logger_1.logger.warn(`Encoding '${csvConfig.encoding}' may not be supported in scenario ${scenarioName}`);
278
+ }
279
+ }
280
+ async loadEnvironmentConfig(environment, baseDir) {
281
+ const envPaths = [
282
+ path.join(baseDir, 'config', 'environments', `${environment}.yml`),
283
+ path.join(baseDir, 'config', 'environments', `${environment}.yaml`),
284
+ path.join(baseDir, 'config', 'environments', `${environment}.json`),
285
+ path.join(baseDir, 'config', 'environments', `${environment}.ts`),
286
+ path.join(baseDir, `${environment}.yml`),
287
+ path.join(baseDir, `${environment}.yaml`),
288
+ path.join(baseDir, `${environment}.json`),
289
+ path.join(baseDir, `${environment}.ts`)
290
+ ];
291
+ for (const envPath of envPaths) {
292
+ if (fs.existsSync(envPath)) {
293
+ if (envPath.endsWith('.ts')) {
294
+ return await this.parseTypeScript(envPath);
295
+ }
296
+ else {
297
+ const envContent = fs.readFileSync(envPath, 'utf8');
298
+ return this.parseContent(envContent);
299
+ }
300
+ }
301
+ }
302
+ throw new Error(`Environment configuration not found for: ${environment}. Searched paths: ${envPaths.join(', ')}`);
303
+ }
304
+ mergeConfigs(base, env) {
305
+ const mergeReportConfig = (baseReport, envReport) => {
306
+ if (!baseReport && !envReport)
307
+ return undefined;
308
+ return {
309
+ generate: false,
310
+ output: 'report.html',
311
+ ...baseReport,
312
+ ...envReport
313
+ };
314
+ };
315
+ return {
316
+ ...base,
317
+ global: { ...base.global, ...env.global },
318
+ load: { ...base.load, ...env.load },
319
+ scenarios: env.scenarios || base.scenarios,
320
+ outputs: env.outputs || base.outputs,
321
+ report: mergeReportConfig(base.report, env.report),
322
+ workers: env.workers || base.workers
323
+ };
324
+ }
325
+ processTemplates(config, _context) {
326
+ const configStr = JSON.stringify(config);
327
+ return JSON.parse(configStr);
328
+ }
329
+ }
330
+ exports.ConfigParser = ConfigParser;
@@ -0,0 +1,74 @@
1
+ export interface GlobalConfig {
2
+ base_url?: string;
3
+ wsdl_url?: string;
4
+ timeout?: number;
5
+ think_time?: string | number;
6
+ headers?: Record<string, string>;
7
+ variables?: Record<string, any>;
8
+ browser?: BrowserConfig;
9
+ faker?: FakerConfig;
10
+ debug?: DebugConfig;
11
+ /** Global CSV data configuration - variables available across all scenarios */
12
+ csv_data?: GlobalCSVConfig;
13
+ /** CSV data access mode: next (round-robin), unique (exhaustible), random */
14
+ csv_mode?: 'next' | 'unique' | 'random';
15
+ }
16
+ export interface GlobalCSVConfig {
17
+ /** Path to the CSV file */
18
+ file: string;
19
+ /** Column delimiter (default: ',') */
20
+ delimiter?: string;
21
+ /** File encoding (default: 'utf8') */
22
+ encoding?: BufferEncoding;
23
+ /** Skip empty lines (default: true) */
24
+ skipEmptyLines?: boolean;
25
+ /** Skip the first line (header row treated as data) */
26
+ skipFirstLine?: boolean;
27
+ /** Select only specific columns */
28
+ columns?: string[];
29
+ /** Filter expression (e.g., "status=active") */
30
+ filter?: string;
31
+ /** Shuffle data randomly */
32
+ randomize?: boolean;
33
+ /** Restart from beginning when data is exhausted (default: true) */
34
+ cycleOnExhaustion?: boolean;
35
+ /** Map CSV column names to custom variable names: { "csv_column": "variable_name" } */
36
+ variables?: Record<string, string>;
37
+ }
38
+ export interface FakerConfig {
39
+ locale?: string;
40
+ seed?: number;
41
+ }
42
+ export interface BrowserConfig {
43
+ type: 'chromium' | 'firefox' | 'webkit';
44
+ headless?: boolean;
45
+ viewport?: {
46
+ width: number;
47
+ height: number;
48
+ };
49
+ slow_mo?: number;
50
+ base_url?: string;
51
+ highlight?: boolean | HighlightConfig;
52
+ clear_storage?: boolean | ClearStorageConfig;
53
+ }
54
+ export interface ClearStorageConfig {
55
+ local_storage?: boolean;
56
+ session_storage?: boolean;
57
+ cookies?: boolean;
58
+ cache?: boolean;
59
+ }
60
+ export interface HighlightConfig {
61
+ enabled: boolean;
62
+ duration?: number;
63
+ color?: string;
64
+ style?: 'border' | 'background' | 'both';
65
+ }
66
+ export interface DebugConfig {
67
+ capture_request_headers?: boolean;
68
+ capture_request_body?: boolean;
69
+ capture_response_headers?: boolean;
70
+ capture_response_body?: boolean;
71
+ max_response_body_size?: number;
72
+ capture_only_failures?: boolean;
73
+ log_level?: 'debug' | 'info' | 'warn' | 'error';
74
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,58 @@
1
+ import { Step } from "./step-types";
2
+ export interface HookScript {
3
+ type: 'inline' | 'file' | 'steps';
4
+ content?: string;
5
+ file?: string;
6
+ steps?: Step[];
7
+ timeout?: number;
8
+ continueOnError?: boolean;
9
+ }
10
+ export interface TestHooks {
11
+ beforeTest?: HookScript;
12
+ onTestError?: HookScript;
13
+ teardownTest?: HookScript;
14
+ }
15
+ export interface VUHooks {
16
+ beforeVU?: HookScript;
17
+ teardownVU?: HookScript;
18
+ }
19
+ export interface ScenarioHooks {
20
+ beforeScenario?: HookScript;
21
+ teardownScenario?: HookScript;
22
+ }
23
+ export interface LoopHooks {
24
+ beforeLoop?: HookScript;
25
+ afterLoop?: HookScript;
26
+ }
27
+ export interface StepHooks {
28
+ beforeStep?: HookScript;
29
+ onStepError?: HookScript;
30
+ teardownStep?: HookScript;
31
+ }
32
+ export { Scenario } from './scenario-config';
33
+ export interface ScriptResult {
34
+ success: boolean;
35
+ result?: any;
36
+ error?: Error;
37
+ duration: number;
38
+ variables?: Record<string, any>;
39
+ }
40
+ export interface ScriptContext {
41
+ test_name: string;
42
+ vu_id: number;
43
+ scenario_name?: string;
44
+ loop_iteration?: number;
45
+ step_name?: string;
46
+ step_type?: string;
47
+ variables: Record<string, any>;
48
+ extracted_data: Record<string, any>;
49
+ csv_data?: Record<string, any>;
50
+ metrics?: any;
51
+ logger?: any;
52
+ error?: Error;
53
+ last_step_result?: any;
54
+ test_start_time?: number;
55
+ scenario_start_time?: number;
56
+ loop_start_time?: number;
57
+ step_start_time?: number;
58
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ // Hooks interfaces for test lifecycle management
3
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,33 @@
1
+ export interface ImportableEndpoint {
2
+ id: string;
3
+ name: string;
4
+ method: string;
5
+ path: string;
6
+ description?: string;
7
+ parameters?: Parameter[];
8
+ requestBody?: RequestBodySchema;
9
+ responses?: ResponseSchema[];
10
+ tags?: string[];
11
+ selected?: boolean;
12
+ }
13
+ export interface Parameter {
14
+ name: string;
15
+ in: 'query' | 'header' | 'path' | 'cookie';
16
+ required: boolean;
17
+ type: string;
18
+ description?: string;
19
+ example?: any;
20
+ enum?: any[];
21
+ }
22
+ export interface RequestBodySchema {
23
+ contentType: string;
24
+ schema: any;
25
+ example?: any;
26
+ required: boolean;
27
+ }
28
+ export interface ResponseSchema {
29
+ statusCode: number;
30
+ contentType: string;
31
+ schema: any;
32
+ example?: any;
33
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,11 @@
1
+ export * from './test-configuration';
2
+ export * from './load-config';
3
+ export * from './scenario-config';
4
+ export * from './step-types';
5
+ export * from './output-config';
6
+ export * from './report-config';
7
+ export * from './worker-config';
8
+ export * from './global-config';
9
+ export * from './runtime-types';
10
+ export * from './hooks';
11
+ export * from './import-types';
@@ -0,0 +1,27 @@
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./test-configuration"), exports);
18
+ __exportStar(require("./load-config"), exports);
19
+ __exportStar(require("./scenario-config"), exports);
20
+ __exportStar(require("./step-types"), exports);
21
+ __exportStar(require("./output-config"), exports);
22
+ __exportStar(require("./report-config"), exports);
23
+ __exportStar(require("./worker-config"), exports);
24
+ __exportStar(require("./global-config"), exports);
25
+ __exportStar(require("./runtime-types"), exports);
26
+ __exportStar(require("./hooks"), exports);
27
+ __exportStar(require("./import-types"), exports);
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Load configuration supports either:
3
+ * 1. Single load pattern (simple)
4
+ * 2. Array of load phases (executed sequentially)
5
+ */
6
+ export type LoadConfig = LoadPhase | LoadPhase[];
7
+ /**
8
+ * A single load phase configuration
9
+ * Multiple phases are executed sequentially
10
+ */
11
+ export interface LoadPhase {
12
+ name?: string;
13
+ pattern: 'basic' | 'stepping' | 'arrivals';
14
+ vus?: number;
15
+ virtual_users?: number;
16
+ ramp_up?: string;
17
+ duration: string;
18
+ steps?: LoadStep[];
19
+ rate?: number;
20
+ }
21
+ /**
22
+ * Load step for stepping pattern
23
+ */
24
+ export interface LoadStep {
25
+ users: number;
26
+ duration: string;
27
+ ramp_up?: string;
28
+ }
29
+ /**
30
+ * Helper to get first/primary load phase
31
+ */
32
+ export declare function getPrimaryLoadPhase(load: LoadConfig): LoadPhase;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPrimaryLoadPhase = getPrimaryLoadPhase;
4
+ /**
5
+ * Helper to get first/primary load phase
6
+ */
7
+ function getPrimaryLoadPhase(load) {
8
+ return Array.isArray(load) ? load[0] : load;
9
+ }
@@ -0,0 +1,10 @@
1
+ export interface OutputConfig {
2
+ type: 'csv' | 'json' | 'html' | 'influxdb' | 'graphite' | 'webhook';
3
+ enabled?: boolean;
4
+ file?: string;
5
+ url?: string;
6
+ database?: string;
7
+ tags?: Record<string, string>;
8
+ headers?: Record<string, string>;
9
+ template?: string;
10
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,10 @@
1
+ export interface ReportConfig {
2
+ generate?: boolean;
3
+ output: string;
4
+ percentiles?: number[];
5
+ template?: string;
6
+ title?: string;
7
+ include_charts?: boolean;
8
+ include_raw_data?: boolean;
9
+ custom_metrics?: string[];
10
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,6 @@
1
+ export interface VUContext {
2
+ vu_id: number;
3
+ iteration: number;
4
+ variables: Record<string, any>;
5
+ extracted_data: Record<string, any>;
6
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,30 @@
1
+ import { CSVDataConfig } from '../../core/csv-data-provider';
2
+ import { Step } from './step-types';
3
+ import { ScenarioHooks, LoopHooks } from './hooks';
4
+ export interface Scenario {
5
+ name: string;
6
+ description?: string;
7
+ weight?: number;
8
+ loop?: number | LoopConfig;
9
+ think_time?: string | number;
10
+ setup?: string;
11
+ teardown?: string;
12
+ variables?: Record<string, any>;
13
+ steps: Step[];
14
+ csv_data?: CSVDataConfig;
15
+ csv_mode?: 'next' | 'unique' | 'random';
16
+ condition?: string;
17
+ enabled?: boolean;
18
+ hooks?: ScenarioHooks & LoopHooks;
19
+ }
20
+ /**
21
+ * Enhanced loop configuration for scenarios
22
+ */
23
+ export interface LoopConfig {
24
+ count?: number;
25
+ duration?: string;
26
+ mode?: 'count' | 'duration' | 'while' | 'until';
27
+ condition?: string;
28
+ break_on_error?: boolean;
29
+ max_errors?: number;
30
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });