@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,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.testData = exports.faker = exports.load = exports.test = exports.LoadBuilder = exports.ScenarioBuilder = exports.TestBuilder = void 0;
4
+ var test_builder_1 = require("./test-builder");
5
+ Object.defineProperty(exports, "TestBuilder", { enumerable: true, get: function () { return test_builder_1.TestBuilder; } });
6
+ Object.defineProperty(exports, "ScenarioBuilder", { enumerable: true, get: function () { return test_builder_1.ScenarioBuilder; } });
7
+ Object.defineProperty(exports, "LoadBuilder", { enumerable: true, get: function () { return test_builder_1.LoadBuilder; } });
8
+ Object.defineProperty(exports, "test", { enumerable: true, get: function () { return test_builder_1.test; } });
9
+ Object.defineProperty(exports, "load", { enumerable: true, get: function () { return test_builder_1.load; } });
10
+ Object.defineProperty(exports, "faker", { enumerable: true, get: function () { return test_builder_1.faker; } });
11
+ Object.defineProperty(exports, "testData", { enumerable: true, get: function () { return test_builder_1.testData; } });
@@ -0,0 +1,111 @@
1
+ import type { TestConfiguration, Scenario, Step, LoadConfig, LoadPhase, GlobalConfig, OutputConfig } from '../config';
2
+ import { getFaker } from '../utils/faker-manager';
3
+ export interface ScenarioContext {
4
+ vu_id: number | string;
5
+ iteration: number;
6
+ variables: Record<string, any>;
7
+ page?: any;
8
+ request?: any;
9
+ [key: string]: any;
10
+ }
11
+ export declare class ScenarioBuilder {
12
+ private parent;
13
+ private scenario;
14
+ constructor(parent: TestBuilder, name: string, weight: number);
15
+ description(desc: string): this;
16
+ loop(count: number): this;
17
+ thinkTime(time: string | number): this;
18
+ variables(vars: Record<string, any>): this;
19
+ withCSV(file: string, options?: any): this;
20
+ beforeScenario(script: string | ((context: ScenarioContext) => Promise<void>)): this;
21
+ afterScenario(script: string | ((context: ScenarioContext) => Promise<void>)): this;
22
+ goto(url: string): this;
23
+ click(selector: string): this;
24
+ fill(selector: string, value: any): this;
25
+ select(selector: string, value: string): this;
26
+ expectVisible(selector: string, name?: string): this;
27
+ expectText(selector: string, text: string, name?: string): this;
28
+ expectNotVisible(selector: string, name?: string): this;
29
+ wait(duration: string | number): this;
30
+ get(path: string, options?: any): this;
31
+ post(path: string, body?: any, options?: any): this;
32
+ put(path: string, body?: any, options?: any): this;
33
+ patch(path: string, body?: any, options?: any): this;
34
+ delete(path: string, options?: any): this;
35
+ request(method: string, path: string, options?: any): this;
36
+ withBasicAuth(username: string, password: string): this;
37
+ withBearerToken(token: string): this;
38
+ withHeaders(headers: Record<string, string>): this;
39
+ withQuery(params: Record<string, string | number | boolean>): this;
40
+ withThinkTime(time: string | number): this;
41
+ extract(name: string, expression: string, type?: 'json_path' | 'regex'): this;
42
+ check(type: string, value: any, description?: string): this;
43
+ soap(operation: string, args: any, wsdl?: string): this;
44
+ step(name: string, script: string | ((context: ScenarioContext) => Promise<void>)): this;
45
+ addStep(step: Step): this;
46
+ done(): TestBuilder;
47
+ endScenario(): TestBuilder;
48
+ }
49
+ export declare class LoadBuilder {
50
+ private loadConfig;
51
+ name(name: string): this;
52
+ pattern(pattern: 'basic' | 'stepping' | 'arrivals'): this;
53
+ virtualUsers(count: number): this;
54
+ vus(count: number): this;
55
+ rampUp(duration: string): this;
56
+ duration(duration: string): this;
57
+ rate(requestsPerSecond: number): this;
58
+ steps(steps: any[]): this;
59
+ build(): LoadPhase;
60
+ }
61
+ export declare function test(name: string): TestBuilder;
62
+ export declare function load(): LoadBuilder;
63
+ /**
64
+ * Fluent DSL for building test configurations
65
+ *
66
+ * Usage:
67
+ * const config = test('My Test')
68
+ * .baseUrl('https://example.com')
69
+ * .withBrowser('chromium', { headless: false })
70
+ * .scenario('User Journey')
71
+ * .goto('/')
72
+ * .click('#login')
73
+ * .fill('#username', 'test@example.com')
74
+ * .expectVisible('#dashboard')
75
+ * .done()
76
+ * .withLoad({ pattern: 'basic', virtualUsers: 10 })
77
+ * .build();
78
+ */
79
+ export declare class TestBuilder {
80
+ private config;
81
+ constructor(name: string);
82
+ configuration(confis: GlobalConfig): this;
83
+ description(desc: string): this;
84
+ baseUrl(url: string): this;
85
+ timeout(ms: number): this;
86
+ thinkTime(time: string | number): this;
87
+ headers(headers: Record<string, string>): this;
88
+ withBrowser(type: 'chromium' | 'firefox' | 'webkit', options?: any): this;
89
+ withWSDL(url: string): this;
90
+ variables(vars: Record<string, any>): this;
91
+ scenario(name: string, weight?: number): ScenarioBuilder;
92
+ addScenario(scenario: Scenario): this;
93
+ withLoad(load: LoadConfig | LoadBuilder | LoadBuilder[]): this;
94
+ withLoadPhases(...phases: (LoadPhase | LoadBuilder)[]): this;
95
+ withOutput(type: string, options: Partial<OutputConfig>): this;
96
+ withJSONOutput(file: string): this;
97
+ withCSVOutput(file: string): this;
98
+ withReport(output?: string): this;
99
+ build(): TestConfiguration;
100
+ run(): Promise<void>;
101
+ }
102
+ export { getFaker as faker };
103
+ export declare const testData: {
104
+ email: () => string;
105
+ password: () => string;
106
+ firstName: () => string;
107
+ lastName: () => string;
108
+ phone: () => string;
109
+ uuid: () => string;
110
+ randomInt: (min: number, max: number) => number;
111
+ };
@@ -0,0 +1,514 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.testData = exports.faker = exports.TestBuilder = exports.LoadBuilder = exports.ScenarioBuilder = void 0;
37
+ exports.test = test;
38
+ exports.load = load;
39
+ const faker_manager_1 = require("../utils/faker-manager");
40
+ Object.defineProperty(exports, "faker", { enumerable: true, get: function () { return faker_manager_1.getFaker; } });
41
+ class ScenarioBuilder {
42
+ constructor(parent, name, weight) {
43
+ this.scenario = {
44
+ steps: []
45
+ };
46
+ this.parent = parent;
47
+ this.scenario.name = name;
48
+ this.scenario.weight = weight;
49
+ }
50
+ description(desc) {
51
+ this.scenario.description = desc;
52
+ return this;
53
+ }
54
+ loop(count) {
55
+ this.scenario.loop = count;
56
+ return this;
57
+ }
58
+ thinkTime(time) {
59
+ this.scenario.think_time = time;
60
+ return this;
61
+ }
62
+ variables(vars) {
63
+ this.scenario.variables = { ...this.scenario.variables, ...vars };
64
+ return this;
65
+ }
66
+ withCSV(file, options) {
67
+ this.scenario.csv_data = { file, ...options };
68
+ return this;
69
+ }
70
+ // Updated hook methods with context parameter
71
+ beforeScenario(script) {
72
+ const scriptStr = typeof script === 'function' ? script.toString() : script;
73
+ this.scenario.hooks = {
74
+ ...this.scenario.hooks,
75
+ beforeScenario: { script: scriptStr }
76
+ };
77
+ return this;
78
+ }
79
+ afterScenario(script) {
80
+ const scriptStr = typeof script === 'function' ? script.toString() : script;
81
+ this.scenario.hooks = {
82
+ ...this.scenario.hooks,
83
+ afterScenario: { script: scriptStr }
84
+ };
85
+ return this;
86
+ }
87
+ // Web step methods
88
+ goto(url) {
89
+ return this.addStep({
90
+ name: `Navigate to ${url}`,
91
+ type: 'web',
92
+ action: { command: 'goto', url }
93
+ });
94
+ }
95
+ click(selector) {
96
+ return this.addStep({
97
+ name: `Click ${selector}`,
98
+ type: 'web',
99
+ action: { command: 'click', selector }
100
+ });
101
+ }
102
+ fill(selector, value) {
103
+ const actualValue = typeof value === 'string' ? value : value.toString();
104
+ return this.addStep({
105
+ name: `Fill ${selector}`,
106
+ type: 'web',
107
+ action: { command: 'fill', selector, value: actualValue }
108
+ });
109
+ }
110
+ select(selector, value) {
111
+ return this.addStep({
112
+ name: `Select ${value} in ${selector}`,
113
+ type: 'web',
114
+ action: { command: 'select', selector, value }
115
+ });
116
+ }
117
+ // press(selector: string, key: string): this {
118
+ // return this.addStep({
119
+ // name: `Press ${key} on ${selector}`,
120
+ // type: 'web',
121
+ // action: { command: 'press', selector, key }
122
+ // });
123
+ // }
124
+ expectVisible(selector, name) {
125
+ return this.addStep({
126
+ name: name || `Verify ${selector} is visible`,
127
+ type: 'web',
128
+ action: {
129
+ command: 'verify_visible',
130
+ selector,
131
+ ...(name && { name })
132
+ }
133
+ });
134
+ }
135
+ expectText(selector, text, name) {
136
+ return this.addStep({
137
+ name: name || `Verify ${selector} contains ${text}`,
138
+ type: 'web',
139
+ action: {
140
+ command: 'verify_text',
141
+ selector,
142
+ expected_text: text,
143
+ ...(name && { name })
144
+ }
145
+ });
146
+ }
147
+ expectNotVisible(selector, name) {
148
+ return this.addStep({
149
+ name: name || `Verify ${selector} is not visible`,
150
+ type: 'web',
151
+ action: {
152
+ command: 'verify_not_exists',
153
+ selector,
154
+ ...(name && { name })
155
+ }
156
+ });
157
+ }
158
+ wait(duration) {
159
+ const durationStr = typeof duration === 'number' ? `${duration}s` : duration;
160
+ return this.addStep({
161
+ name: `Wait ${durationStr}`,
162
+ type: 'wait',
163
+ duration: durationStr
164
+ });
165
+ }
166
+ // REST API step methods
167
+ get(path, options) {
168
+ return this.request('GET', path, options);
169
+ }
170
+ post(path, body, options) {
171
+ return this.request('POST', path, { ...options, json: body });
172
+ }
173
+ put(path, body, options) {
174
+ return this.request('PUT', path, { ...options, json: body });
175
+ }
176
+ patch(path, body, options) {
177
+ return this.request('PATCH', path, { ...options, json: body });
178
+ }
179
+ delete(path, options) {
180
+ return this.request('DELETE', path, options);
181
+ }
182
+ request(method, path, options) {
183
+ const step = {
184
+ name: options?.name || `${method} ${path}`,
185
+ type: 'rest',
186
+ method,
187
+ path
188
+ };
189
+ if (options?.headers)
190
+ step.headers = options.headers;
191
+ if (options?.json)
192
+ step.json = options.json;
193
+ if (options?.body)
194
+ step.body = options.body;
195
+ if (options?.xml)
196
+ step.xml = options.xml;
197
+ if (options?.form)
198
+ step.form = options.form;
199
+ if (options?.multipart)
200
+ step.multipart = options.multipart;
201
+ if (options?.query)
202
+ step.query = options.query;
203
+ if (options?.auth)
204
+ step.auth = options.auth;
205
+ if (options?.extract)
206
+ step.extract = options.extract;
207
+ if (options?.checks)
208
+ step.checks = options.checks;
209
+ if (options?.timeout)
210
+ step.timeout = options.timeout;
211
+ return this.addStep(step);
212
+ }
213
+ // Enhanced methods for different auth types
214
+ withBasicAuth(username, password) {
215
+ const lastStep = this.scenario.steps[this.scenario.steps.length - 1];
216
+ if (lastStep.type === 'rest') {
217
+ lastStep.auth = { type: 'basic', username, password };
218
+ }
219
+ return this;
220
+ }
221
+ withBearerToken(token) {
222
+ const lastStep = this.scenario.steps[this.scenario.steps.length - 1];
223
+ if (lastStep.type === 'rest') {
224
+ lastStep.auth = { type: 'bearer', token };
225
+ }
226
+ return this;
227
+ }
228
+ withHeaders(headers) {
229
+ const lastStep = this.scenario.steps[this.scenario.steps.length - 1];
230
+ if (lastStep.type === 'rest') {
231
+ lastStep.headers = { ...lastStep.headers, ...headers };
232
+ }
233
+ return this;
234
+ }
235
+ withQuery(params) {
236
+ const lastStep = this.scenario.steps[this.scenario.steps.length - 1];
237
+ if (lastStep.type === 'rest') {
238
+ lastStep.query = params;
239
+ }
240
+ return this;
241
+ }
242
+ // Add think time to the last step
243
+ withThinkTime(time) {
244
+ const lastStep = this.scenario.steps[this.scenario.steps.length - 1];
245
+ lastStep.think_time = time;
246
+ return this;
247
+ }
248
+ extract(name, expression, type = 'json_path') {
249
+ const lastStep = this.scenario.steps[this.scenario.steps.length - 1];
250
+ if (!lastStep.extract)
251
+ lastStep.extract = [];
252
+ lastStep.extract.push({ name, expression, type });
253
+ return this;
254
+ }
255
+ check(type, value, description) {
256
+ const lastStep = this.scenario.steps[this.scenario.steps.length - 1];
257
+ if (!lastStep.checks)
258
+ lastStep.checks = [];
259
+ lastStep.checks.push({ type, value, description });
260
+ return this;
261
+ }
262
+ // SOAP step method
263
+ soap(operation, args, wsdl) {
264
+ return this.addStep({
265
+ name: `SOAP ${operation}`,
266
+ type: 'soap',
267
+ operation,
268
+ args,
269
+ ...(wsdl && { wsdl })
270
+ });
271
+ }
272
+ // Custom step method
273
+ // Updated custom step method with context
274
+ step(name, script) {
275
+ const scriptStr = typeof script === 'function' ?
276
+ `(${script.toString()})(context)` : script;
277
+ return this.addStep({
278
+ name,
279
+ type: 'custom',
280
+ script: scriptStr
281
+ });
282
+ }
283
+ // Add a raw step
284
+ addStep(step) {
285
+ this.scenario.steps = [...(this.scenario.steps || []), step];
286
+ return this;
287
+ }
288
+ // Finish scenario and return to parent
289
+ done() {
290
+ this.parent.addScenario(this.scenario);
291
+ return this.parent;
292
+ }
293
+ // Alias for done()
294
+ endScenario() {
295
+ return this.done();
296
+ }
297
+ }
298
+ exports.ScenarioBuilder = ScenarioBuilder;
299
+ class LoadBuilder {
300
+ constructor() {
301
+ this.loadConfig = {};
302
+ }
303
+ name(name) {
304
+ this.loadConfig.name = name;
305
+ return this;
306
+ }
307
+ pattern(pattern) {
308
+ this.loadConfig.pattern = pattern;
309
+ return this;
310
+ }
311
+ virtualUsers(count) {
312
+ this.loadConfig.virtual_users = count;
313
+ return this;
314
+ }
315
+ vus(count) {
316
+ this.loadConfig.vus = count;
317
+ return this;
318
+ }
319
+ rampUp(duration) {
320
+ this.loadConfig.ramp_up = duration;
321
+ return this;
322
+ }
323
+ duration(duration) {
324
+ this.loadConfig.duration = duration;
325
+ return this;
326
+ }
327
+ rate(requestsPerSecond) {
328
+ this.loadConfig.rate = requestsPerSecond;
329
+ return this;
330
+ }
331
+ steps(steps) {
332
+ this.loadConfig.steps = steps;
333
+ return this;
334
+ }
335
+ build() {
336
+ if (!this.loadConfig.pattern) {
337
+ this.loadConfig.pattern = 'basic';
338
+ }
339
+ if (!this.loadConfig.duration) {
340
+ this.loadConfig.duration = '1m'; // Default duration
341
+ }
342
+ return this.loadConfig;
343
+ }
344
+ }
345
+ exports.LoadBuilder = LoadBuilder;
346
+ // Factory functions for convenience
347
+ function test(name) {
348
+ return new TestBuilder(name);
349
+ }
350
+ function load() {
351
+ return new LoadBuilder();
352
+ }
353
+ /**
354
+ * Fluent DSL for building test configurations
355
+ *
356
+ * Usage:
357
+ * const config = test('My Test')
358
+ * .baseUrl('https://example.com')
359
+ * .withBrowser('chromium', { headless: false })
360
+ * .scenario('User Journey')
361
+ * .goto('/')
362
+ * .click('#login')
363
+ * .fill('#username', 'test@example.com')
364
+ * .expectVisible('#dashboard')
365
+ * .done()
366
+ * .withLoad({ pattern: 'basic', virtualUsers: 10 })
367
+ * .build();
368
+ */
369
+ class TestBuilder {
370
+ constructor(name) {
371
+ this.config = {
372
+ scenarios: [],
373
+ outputs: [],
374
+ global: {}
375
+ };
376
+ this.config.name = name;
377
+ }
378
+ configuration(confis) {
379
+ this.config = confis;
380
+ return this;
381
+ }
382
+ description(desc) {
383
+ this.config.description = desc;
384
+ return this;
385
+ }
386
+ // Global configuration methods
387
+ baseUrl(url) {
388
+ this.config.global = { ...this.config.global, base_url: url };
389
+ return this;
390
+ }
391
+ timeout(ms) {
392
+ this.config.global = { ...this.config.global, timeout: ms };
393
+ return this;
394
+ }
395
+ thinkTime(time) {
396
+ this.config.global = { ...this.config.global, think_time: time };
397
+ return this;
398
+ }
399
+ headers(headers) {
400
+ this.config.global = {
401
+ ...this.config.global,
402
+ headers: { ...(this.config.global?.headers || {}), ...headers }
403
+ };
404
+ return this;
405
+ }
406
+ withBrowser(type, options) {
407
+ this.config.global = {
408
+ ...this.config.global,
409
+ browser: {
410
+ type,
411
+ ...options
412
+ }
413
+ };
414
+ return this;
415
+ }
416
+ withWSDL(url) {
417
+ this.config.global = { ...this.config.global, wsdl_url: url };
418
+ return this;
419
+ }
420
+ variables(vars) {
421
+ if (!this.config.global) {
422
+ this.config.global = {};
423
+ }
424
+ this.config.global = {
425
+ ...this.config.global,
426
+ variables: { ...(this.config.global.variables || {}), ...vars }
427
+ };
428
+ return this;
429
+ }
430
+ // Create a new scenario
431
+ scenario(name, weight = 100) {
432
+ return new ScenarioBuilder(this, name, weight);
433
+ }
434
+ // Add a complete scenario
435
+ addScenario(scenario) {
436
+ this.config.scenarios = [...(this.config.scenarios || []), scenario];
437
+ return this;
438
+ }
439
+ // Load configuration - supports single phase or array of phases
440
+ withLoad(load) {
441
+ if (Array.isArray(load)) {
442
+ // Array of LoadBuilders - build each one
443
+ this.config.load = load.map(lb => lb instanceof LoadBuilder ? lb.build() : lb);
444
+ }
445
+ else if (load instanceof LoadBuilder) {
446
+ this.config.load = load.build();
447
+ }
448
+ else {
449
+ this.config.load = load;
450
+ }
451
+ return this;
452
+ }
453
+ // Add multiple load phases (sequential execution)
454
+ withLoadPhases(...phases) {
455
+ this.config.load = phases.map(phase => phase instanceof LoadBuilder ? phase.build() : phase);
456
+ return this;
457
+ }
458
+ // Output configuration
459
+ withOutput(type, options) {
460
+ this.config.outputs = [
461
+ ...(this.config.outputs || []),
462
+ { type, ...options }
463
+ ];
464
+ return this;
465
+ }
466
+ withJSONOutput(file) {
467
+ return this.withOutput('json', { file });
468
+ }
469
+ withCSVOutput(file) {
470
+ return this.withOutput('csv', { file });
471
+ }
472
+ // Report configuration
473
+ withReport(output = 'report.html') {
474
+ this.config.report = {
475
+ generate: true,
476
+ output
477
+ };
478
+ return this;
479
+ }
480
+ // Build the final configuration
481
+ build() {
482
+ if (!this.config.name)
483
+ throw new Error('Test name is required');
484
+ if (!this.config.load) {
485
+ // Default load configuration
486
+ this.config.load = {
487
+ pattern: 'basic',
488
+ virtual_users: 1,
489
+ ramp_up: '10s',
490
+ duration: '1m'
491
+ };
492
+ }
493
+ if (!this.config.scenarios || this.config.scenarios.length === 0) {
494
+ throw new Error('At least one scenario is required');
495
+ }
496
+ return this.config;
497
+ }
498
+ // Run the test directly
499
+ async run() {
500
+ const { TestRunner } = await Promise.resolve().then(() => __importStar(require('../core/test-runner')));
501
+ const runner = new TestRunner(this.build());
502
+ await runner.run();
503
+ }
504
+ }
505
+ exports.TestBuilder = TestBuilder;
506
+ exports.testData = {
507
+ email: () => (0, faker_manager_1.getFaker)().internet.email(),
508
+ password: () => (0, faker_manager_1.getFaker)().internet.password(),
509
+ firstName: () => (0, faker_manager_1.getFaker)().person.firstName(),
510
+ lastName: () => (0, faker_manager_1.getFaker)().person.lastName(),
511
+ phone: () => (0, faker_manager_1.getFaker)().phone.number(),
512
+ uuid: () => (0, faker_manager_1.getFaker)().string.uuid(),
513
+ randomInt: (min, max) => (0, faker_manager_1.getFaker)().number.int({ min, max })
514
+ };
@@ -0,0 +1,17 @@
1
+ import { ImportableEndpoint } from "../config/types/import-types";
2
+ export declare class HARImporter {
3
+ private har;
4
+ constructor(harContent: any);
5
+ extractEndpoints(): ImportableEndpoint[];
6
+ generateScenarios(selectedEndpoints: ImportableEndpoint[]): any[];
7
+ private isAPIRequest;
8
+ private extractPath;
9
+ private extractParametersFromHAR;
10
+ private extractRequestBodyFromHAR;
11
+ private extractContentType;
12
+ private deduplicateEndpoints;
13
+ private extractHeadersFromEndpoint;
14
+ private parseRequestBody;
15
+ private generateHARExtractions;
16
+ private hasField;
17
+ }