qa360 1.4.5 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/README.md +1 -1
  2. package/dist/commands/ai.d.ts +41 -0
  3. package/dist/commands/ai.js +499 -0
  4. package/dist/commands/ask.js +12 -12
  5. package/dist/commands/coverage.d.ts +8 -0
  6. package/dist/commands/coverage.js +252 -0
  7. package/dist/commands/explain.d.ts +27 -0
  8. package/dist/commands/explain.js +630 -0
  9. package/dist/commands/flakiness.d.ts +73 -0
  10. package/dist/commands/flakiness.js +435 -0
  11. package/dist/commands/generate.d.ts +66 -0
  12. package/dist/commands/generate.js +438 -0
  13. package/dist/commands/init.d.ts +56 -9
  14. package/dist/commands/init.js +217 -10
  15. package/dist/commands/monitor.d.ts +27 -0
  16. package/dist/commands/monitor.js +225 -0
  17. package/dist/commands/ollama.d.ts +40 -0
  18. package/dist/commands/ollama.js +301 -0
  19. package/dist/commands/pack.d.ts +37 -9
  20. package/dist/commands/pack.js +240 -141
  21. package/dist/commands/regression.d.ts +8 -0
  22. package/dist/commands/regression.js +340 -0
  23. package/dist/commands/repair.d.ts +26 -0
  24. package/dist/commands/repair.js +307 -0
  25. package/dist/commands/retry.d.ts +43 -0
  26. package/dist/commands/retry.js +275 -0
  27. package/dist/commands/run.d.ts +8 -3
  28. package/dist/commands/run.js +45 -31
  29. package/dist/commands/slo.d.ts +8 -0
  30. package/dist/commands/slo.js +327 -0
  31. package/dist/core/adapters/playwright-native-api.d.ts +183 -0
  32. package/dist/core/adapters/playwright-native-api.js +461 -0
  33. package/dist/core/adapters/playwright-ui.d.ts +7 -0
  34. package/dist/core/adapters/playwright-ui.js +29 -1
  35. package/dist/core/ai/anthropic-provider.d.ts +50 -0
  36. package/dist/core/ai/anthropic-provider.js +211 -0
  37. package/dist/core/ai/deepseek-provider.d.ts +81 -0
  38. package/dist/core/ai/deepseek-provider.js +254 -0
  39. package/dist/core/ai/index.d.ts +60 -0
  40. package/dist/core/ai/index.js +18 -0
  41. package/dist/core/ai/llm-client.d.ts +45 -0
  42. package/dist/core/ai/llm-client.js +7 -0
  43. package/dist/core/ai/mock-provider.d.ts +49 -0
  44. package/dist/core/ai/mock-provider.js +121 -0
  45. package/dist/core/ai/ollama-provider.d.ts +78 -0
  46. package/dist/core/ai/ollama-provider.js +192 -0
  47. package/dist/core/ai/openai-provider.d.ts +48 -0
  48. package/dist/core/ai/openai-provider.js +188 -0
  49. package/dist/core/ai/provider-factory.d.ts +160 -0
  50. package/dist/core/ai/provider-factory.js +269 -0
  51. package/dist/core/auth/api-key-provider.d.ts +16 -0
  52. package/dist/core/auth/api-key-provider.js +63 -0
  53. package/dist/core/auth/aws-iam-provider.d.ts +35 -0
  54. package/dist/core/auth/aws-iam-provider.js +177 -0
  55. package/dist/core/auth/azure-ad-provider.d.ts +15 -0
  56. package/dist/core/auth/azure-ad-provider.js +99 -0
  57. package/dist/core/auth/basic-auth-provider.d.ts +26 -0
  58. package/dist/core/auth/basic-auth-provider.js +111 -0
  59. package/dist/core/auth/gcp-adc-provider.d.ts +27 -0
  60. package/dist/core/auth/gcp-adc-provider.js +126 -0
  61. package/dist/core/auth/index.d.ts +238 -0
  62. package/dist/core/auth/index.js +82 -0
  63. package/dist/core/auth/jwt-provider.d.ts +19 -0
  64. package/dist/core/auth/jwt-provider.js +160 -0
  65. package/dist/core/auth/manager.d.ts +84 -0
  66. package/dist/core/auth/manager.js +230 -0
  67. package/dist/core/auth/oauth2-provider.d.ts +17 -0
  68. package/dist/core/auth/oauth2-provider.js +114 -0
  69. package/dist/core/auth/totp-provider.d.ts +31 -0
  70. package/dist/core/auth/totp-provider.js +134 -0
  71. package/dist/core/auth/ui-login-provider.d.ts +26 -0
  72. package/dist/core/auth/ui-login-provider.js +198 -0
  73. package/dist/core/cache/index.d.ts +7 -0
  74. package/dist/core/cache/index.js +6 -0
  75. package/dist/core/cache/lru-cache.d.ts +203 -0
  76. package/dist/core/cache/lru-cache.js +397 -0
  77. package/dist/core/coverage/analyzer.d.ts +101 -0
  78. package/dist/core/coverage/analyzer.js +415 -0
  79. package/dist/core/coverage/collector.d.ts +74 -0
  80. package/dist/core/coverage/collector.js +459 -0
  81. package/dist/core/coverage/config.d.ts +37 -0
  82. package/dist/core/coverage/config.js +156 -0
  83. package/dist/core/coverage/index.d.ts +11 -0
  84. package/dist/core/coverage/index.js +15 -0
  85. package/dist/core/coverage/types.d.ts +267 -0
  86. package/dist/core/coverage/types.js +6 -0
  87. package/dist/core/coverage/vault.d.ts +95 -0
  88. package/dist/core/coverage/vault.js +405 -0
  89. package/dist/core/dashboard/assets.d.ts +6 -0
  90. package/dist/core/dashboard/assets.js +690 -0
  91. package/dist/core/dashboard/index.d.ts +6 -0
  92. package/dist/core/dashboard/index.js +5 -0
  93. package/dist/core/dashboard/server.d.ts +72 -0
  94. package/dist/core/dashboard/server.js +354 -0
  95. package/dist/core/dashboard/types.d.ts +70 -0
  96. package/dist/core/dashboard/types.js +5 -0
  97. package/dist/core/discoverer/index.d.ts +115 -0
  98. package/dist/core/discoverer/index.js +250 -0
  99. package/dist/core/flakiness/index.d.ts +228 -0
  100. package/dist/core/flakiness/index.js +384 -0
  101. package/dist/core/generation/code-formatter.d.ts +111 -0
  102. package/dist/core/generation/code-formatter.js +307 -0
  103. package/dist/core/generation/code-generator.d.ts +144 -0
  104. package/dist/core/generation/code-generator.js +293 -0
  105. package/dist/core/generation/generator.d.ts +40 -0
  106. package/dist/core/generation/generator.js +76 -0
  107. package/dist/core/generation/index.d.ts +30 -0
  108. package/dist/core/generation/index.js +28 -0
  109. package/dist/core/generation/pack-generator.d.ts +107 -0
  110. package/dist/core/generation/pack-generator.js +416 -0
  111. package/dist/core/generation/prompt-builder.d.ts +132 -0
  112. package/dist/core/generation/prompt-builder.js +672 -0
  113. package/dist/core/generation/source-analyzer.d.ts +213 -0
  114. package/dist/core/generation/source-analyzer.js +657 -0
  115. package/dist/core/generation/test-optimizer.d.ts +117 -0
  116. package/dist/core/generation/test-optimizer.js +328 -0
  117. package/dist/core/generation/types.d.ts +214 -0
  118. package/dist/core/generation/types.js +4 -0
  119. package/dist/core/index.d.ts +23 -1
  120. package/dist/core/index.js +39 -0
  121. package/dist/core/pack/validator.js +31 -1
  122. package/dist/core/pack-v2/index.d.ts +9 -0
  123. package/dist/core/pack-v2/index.js +8 -0
  124. package/dist/core/pack-v2/loader.d.ts +62 -0
  125. package/dist/core/pack-v2/loader.js +231 -0
  126. package/dist/core/pack-v2/migrator.d.ts +56 -0
  127. package/dist/core/pack-v2/migrator.js +455 -0
  128. package/dist/core/pack-v2/validator.d.ts +61 -0
  129. package/dist/core/pack-v2/validator.js +577 -0
  130. package/dist/core/regression/detector.d.ts +107 -0
  131. package/dist/core/regression/detector.js +497 -0
  132. package/dist/core/regression/index.d.ts +9 -0
  133. package/dist/core/regression/index.js +11 -0
  134. package/dist/core/regression/trend-analyzer.d.ts +102 -0
  135. package/dist/core/regression/trend-analyzer.js +345 -0
  136. package/dist/core/regression/types.d.ts +222 -0
  137. package/dist/core/regression/types.js +7 -0
  138. package/dist/core/regression/vault.d.ts +87 -0
  139. package/dist/core/regression/vault.js +289 -0
  140. package/dist/core/repair/engine/fixer.d.ts +24 -0
  141. package/dist/core/repair/engine/fixer.js +226 -0
  142. package/dist/core/repair/engine/suggestion-engine.d.ts +18 -0
  143. package/dist/core/repair/engine/suggestion-engine.js +187 -0
  144. package/dist/core/repair/index.d.ts +10 -0
  145. package/dist/core/repair/index.js +13 -0
  146. package/dist/core/repair/repairer.d.ts +90 -0
  147. package/dist/core/repair/repairer.js +284 -0
  148. package/dist/core/repair/types.d.ts +91 -0
  149. package/dist/core/repair/types.js +6 -0
  150. package/dist/core/repair/utils/error-analyzer.d.ts +28 -0
  151. package/dist/core/repair/utils/error-analyzer.js +264 -0
  152. package/dist/core/retry/flakiness-integration.d.ts +60 -0
  153. package/dist/core/retry/flakiness-integration.js +228 -0
  154. package/dist/core/retry/index.d.ts +14 -0
  155. package/dist/core/retry/index.js +16 -0
  156. package/dist/core/retry/retry-engine.d.ts +80 -0
  157. package/dist/core/retry/retry-engine.js +296 -0
  158. package/dist/core/retry/types.d.ts +178 -0
  159. package/dist/core/retry/types.js +52 -0
  160. package/dist/core/retry/vault.d.ts +77 -0
  161. package/dist/core/retry/vault.js +304 -0
  162. package/dist/core/runner/e2e-helpers.d.ts +102 -0
  163. package/dist/core/runner/e2e-helpers.js +153 -0
  164. package/dist/core/runner/phase3-runner.d.ts +101 -2
  165. package/dist/core/runner/phase3-runner.js +559 -24
  166. package/dist/core/self-healing/assertion-healer.d.ts +97 -0
  167. package/dist/core/self-healing/assertion-healer.js +371 -0
  168. package/dist/core/self-healing/engine.d.ts +122 -0
  169. package/dist/core/self-healing/engine.js +538 -0
  170. package/dist/core/self-healing/index.d.ts +10 -0
  171. package/dist/core/self-healing/index.js +11 -0
  172. package/dist/core/self-healing/selector-healer.d.ts +103 -0
  173. package/dist/core/self-healing/selector-healer.js +372 -0
  174. package/dist/core/self-healing/types.d.ts +152 -0
  175. package/dist/core/self-healing/types.js +6 -0
  176. package/dist/core/slo/config.d.ts +107 -0
  177. package/dist/core/slo/config.js +360 -0
  178. package/dist/core/slo/index.d.ts +11 -0
  179. package/dist/core/slo/index.js +15 -0
  180. package/dist/core/slo/sli-calculator.d.ts +92 -0
  181. package/dist/core/slo/sli-calculator.js +364 -0
  182. package/dist/core/slo/slo-tracker.d.ts +148 -0
  183. package/dist/core/slo/slo-tracker.js +379 -0
  184. package/dist/core/slo/types.d.ts +281 -0
  185. package/dist/core/slo/types.js +7 -0
  186. package/dist/core/slo/vault.d.ts +102 -0
  187. package/dist/core/slo/vault.js +427 -0
  188. package/dist/core/tui/index.d.ts +7 -0
  189. package/dist/core/tui/index.js +6 -0
  190. package/dist/core/tui/monitor.d.ts +92 -0
  191. package/dist/core/tui/monitor.js +271 -0
  192. package/dist/core/tui/renderer.d.ts +33 -0
  193. package/dist/core/tui/renderer.js +218 -0
  194. package/dist/core/tui/types.d.ts +63 -0
  195. package/dist/core/tui/types.js +5 -0
  196. package/dist/core/types/pack-v2.d.ts +425 -0
  197. package/dist/core/types/pack-v2.js +8 -0
  198. package/dist/core/vault/index.d.ts +116 -0
  199. package/dist/core/vault/index.js +400 -5
  200. package/dist/core/watch/index.d.ts +7 -0
  201. package/dist/core/watch/index.js +6 -0
  202. package/dist/core/watch/watch-mode.d.ts +213 -0
  203. package/dist/core/watch/watch-mode.js +389 -0
  204. package/dist/index.js +68 -68
  205. package/dist/utils/config.d.ts +5 -0
  206. package/dist/utils/config.js +136 -0
  207. package/package.json +5 -1
  208. package/dist/core/adapters/playwright-api.d.ts +0 -82
  209. package/dist/core/adapters/playwright-api.js +0 -264
@@ -0,0 +1,416 @@
1
+ /**
2
+ * QA360 Pack Generator
3
+ *
4
+ * Converts generated test specifications into QA360 pack YAML format.
5
+ * This bridges the gap between AI-generated tests and runnable QA360 packs.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * const generator = new PackGenerator();
10
+ * const packYaml = generator.generateFromApiSpec(apiSpec, {
11
+ * name: 'my-api-tests',
12
+ * version: 2
13
+ * });
14
+ * ```
15
+ */
16
+ /**
17
+ * Pack Generator
18
+ *
19
+ * Converts test specifications into QA360 pack YAML format.
20
+ */
21
+ export class PackGenerator {
22
+ defaults;
23
+ constructor(options = {}) {
24
+ this.defaults = {
25
+ name: options.name ?? 'generated-tests',
26
+ description: options.description ?? 'Auto-generated test pack',
27
+ timeout: options.timeout ?? 30000,
28
+ retries: options.retries ?? 2,
29
+ onFailure: options.onFailure ?? 'continue',
30
+ cacheTtl: options.cacheTtl ?? 300000
31
+ };
32
+ }
33
+ /**
34
+ * Generate pack from API test specification
35
+ */
36
+ generateFromApiSpec(spec, options) {
37
+ const opts = { ...this.defaults, ...options };
38
+ const warnings = [];
39
+ // Build gates from API endpoints
40
+ const gates = {};
41
+ // Group endpoints by type (smoke, full, etc.)
42
+ const smokeEndpoints = spec.endpoints.filter((e) => e.method === 'GET' && (e.path.includes('/health') || e.path.includes('/status') || e.path === '/'));
43
+ const apiEndpoints = spec.endpoints.filter((e) => !smokeEndpoints.includes(e));
44
+ // Add api_smoke gate if we have smoke endpoints
45
+ if (smokeEndpoints.length > 0) {
46
+ gates['api_smoke'] = {
47
+ adapter: 'playwright-native-api',
48
+ config: {
49
+ target: {
50
+ baseUrl: spec.baseUrl,
51
+ smoke: smokeEndpoints.map((e) => this.formatEndpointSpec(e))
52
+ },
53
+ timeout: opts.timeout,
54
+ retries: opts.retries
55
+ },
56
+ options: {
57
+ timeout: opts.timeout,
58
+ retries: opts.retries
59
+ },
60
+ budgets: {
61
+ p95_ms: 2000,
62
+ p99_ms: 5000
63
+ }
64
+ };
65
+ }
66
+ // Add api_full gate if we have other endpoints
67
+ if (apiEndpoints.length > 0) {
68
+ gates['api_full'] = {
69
+ adapter: 'playwright-native-api',
70
+ config: {
71
+ target: {
72
+ baseUrl: spec.baseUrl,
73
+ smoke: apiEndpoints.map((e) => this.formatEndpointSpec(e))
74
+ },
75
+ timeout: opts.timeout,
76
+ retries: opts.retries
77
+ },
78
+ options: {
79
+ timeout: opts.timeout,
80
+ retries: opts.retries
81
+ }
82
+ };
83
+ }
84
+ // Build pack config
85
+ const config = {
86
+ version: 2,
87
+ name: opts.name,
88
+ description: opts.description,
89
+ gates,
90
+ execution: {
91
+ parallel: false,
92
+ on_failure: opts.onFailure === 'stop' ? 'stop' : 'continue'
93
+ }
94
+ };
95
+ // Add auth if specified
96
+ if (spec.auth && spec.auth.type !== 'none') {
97
+ const authType = spec.auth.type === 'bearer' ? 'bearer' :
98
+ spec.auth.type === 'basic' ? 'basic' :
99
+ spec.auth.type === 'api_key' ? 'api_key' :
100
+ spec.auth.type === 'jwt' ? 'jwt' :
101
+ spec.auth.type === 'oauth2' ? 'oauth2' :
102
+ 'bearer';
103
+ config.auth = {
104
+ profiles: {
105
+ default: {
106
+ type: authType,
107
+ config: spec.auth.config || {}
108
+ }
109
+ }
110
+ };
111
+ }
112
+ return {
113
+ success: true,
114
+ yaml: this.toYaml(config),
115
+ config,
116
+ warnings: warnings.length > 0 ? warnings : undefined
117
+ };
118
+ }
119
+ /**
120
+ * Generate pack from UI test specification
121
+ */
122
+ generateFromUiSpec(spec, options) {
123
+ const opts = { ...this.defaults, ...options };
124
+ const warnings = [];
125
+ const gates = {};
126
+ // Add ui_smoke gate for basic page checks
127
+ gates['ui_smoke'] = {
128
+ adapter: 'playwright-ui',
129
+ config: {
130
+ target: {
131
+ baseUrl: spec.baseUrl,
132
+ pages: spec.pages.slice(0, 3).map((p) => ({
133
+ url: p.url,
134
+ name: p.name,
135
+ actions: p.actions.slice(0, 5).map((a) => this.formatPageAction(a))
136
+ }))
137
+ },
138
+ viewport: spec.viewport || { width: 1280, height: 720 }
139
+ },
140
+ options: {
141
+ timeout: opts.timeout,
142
+ retries: opts.retries
143
+ },
144
+ budgets: {
145
+ a11y_min: 80
146
+ }
147
+ };
148
+ // Add ui_full gate if we have more pages
149
+ if (spec.pages.length > 3) {
150
+ gates['ui_full'] = {
151
+ adapter: 'playwright-ui',
152
+ config: {
153
+ target: {
154
+ baseUrl: spec.baseUrl,
155
+ pages: spec.pages.map((p) => ({
156
+ url: p.url,
157
+ name: p.name,
158
+ actions: p.actions.map((a) => this.formatPageAction(a))
159
+ }))
160
+ },
161
+ viewport: spec.viewport || { width: 1280, height: 720 }
162
+ },
163
+ options: {
164
+ timeout: opts.timeout * 2,
165
+ retries: opts.retries
166
+ },
167
+ budgets: {
168
+ a11y_min: 90
169
+ }
170
+ };
171
+ }
172
+ const config = {
173
+ version: 2,
174
+ name: opts.name,
175
+ description: opts.description,
176
+ gates,
177
+ execution: {
178
+ parallel: false,
179
+ on_failure: opts.onFailure === 'stop' ? 'stop' : 'continue'
180
+ }
181
+ };
182
+ return {
183
+ success: true,
184
+ yaml: this.toYaml(config),
185
+ config,
186
+ warnings: warnings.length > 0 ? warnings : undefined
187
+ };
188
+ }
189
+ /**
190
+ * Generate pack from performance test specification
191
+ */
192
+ generateFromPerfSpec(spec, options) {
193
+ const opts = { ...this.defaults, ...options };
194
+ const warnings = [];
195
+ const gates = {};
196
+ // Build budgets from thresholds
197
+ const budgets = {
198
+ p95_ms: this.extractThreshold(spec.options?.thresholds || [], 'p(95)'),
199
+ p99_ms: this.extractThreshold(spec.options?.thresholds || [], 'p(99)')
200
+ };
201
+ // Add perf gate
202
+ gates['perf'] = {
203
+ adapter: 'k6-perf',
204
+ config: {
205
+ target: {
206
+ baseUrl: spec.baseUrl,
207
+ scenarios: spec.scenarios.map((s) => ({
208
+ name: s.name,
209
+ weight: s.weight,
210
+ requests: s.requests.map((r) => ({
211
+ method: r.method,
212
+ path: r.path,
213
+ headers: r.headers,
214
+ body: r.body
215
+ }))
216
+ }))
217
+ },
218
+ options: spec.options || {
219
+ duration: '30s',
220
+ vus: 10,
221
+ maxVus: 50
222
+ }
223
+ },
224
+ budgets
225
+ };
226
+ const config = {
227
+ version: 2,
228
+ name: opts.name,
229
+ description: opts.description,
230
+ gates,
231
+ execution: {
232
+ parallel: false,
233
+ on_failure: opts.onFailure === 'stop' ? 'stop' : 'continue'
234
+ }
235
+ };
236
+ return {
237
+ success: true,
238
+ yaml: this.toYaml(config),
239
+ config,
240
+ warnings: warnings.length > 0 ? warnings : undefined
241
+ };
242
+ }
243
+ /**
244
+ * Generate pack from generic test specification
245
+ */
246
+ generateFromSpec(spec, options) {
247
+ switch (spec.type) {
248
+ case 'api':
249
+ return this.generateFromApiSpec(spec, options);
250
+ case 'ui':
251
+ return this.generateFromUiSpec(spec, options);
252
+ case 'perf':
253
+ return this.generateFromPerfSpec(spec, options);
254
+ case 'unit':
255
+ return {
256
+ success: false,
257
+ yaml: '',
258
+ config: {},
259
+ errors: ['Unit tests are not supported in pack YAML format. Use direct test file generation instead.']
260
+ };
261
+ default:
262
+ return {
263
+ success: false,
264
+ yaml: '',
265
+ config: {},
266
+ errors: [`Unknown test type: ${spec.type}`]
267
+ };
268
+ }
269
+ }
270
+ /**
271
+ * Format endpoint as smoke test spec
272
+ */
273
+ formatEndpointSpec(endpoint) {
274
+ const firstExpectation = endpoint.expectations?.[0];
275
+ const status = firstExpectation?.status ?? 200;
276
+ const statusStr = Array.isArray(status) ? status[0] : status;
277
+ return `${endpoint.method} ${endpoint.path} -> ${statusStr}`;
278
+ }
279
+ /**
280
+ * Format page action
281
+ */
282
+ formatPageAction(action) {
283
+ const formatted = {
284
+ action: action.type
285
+ };
286
+ if (action.selector) {
287
+ formatted.selector = action.selector;
288
+ }
289
+ if (action.value) {
290
+ formatted.value = action.value;
291
+ }
292
+ if (action.timeout) {
293
+ formatted.timeout = action.timeout;
294
+ }
295
+ return formatted;
296
+ }
297
+ /**
298
+ * Extract threshold value from thresholds array
299
+ */
300
+ extractThreshold(thresholds, metric) {
301
+ const threshold = thresholds.find((t) => t.condition.includes(metric));
302
+ if (threshold) {
303
+ const match = threshold.condition.match(/<(\d+)/);
304
+ return match ? parseInt(match[1], 10) : 1000;
305
+ }
306
+ return 1000;
307
+ }
308
+ /**
309
+ * Convert config to YAML string
310
+ * Note: This is a simple YAML generator. For production, use a proper YAML library.
311
+ */
312
+ toYaml(config) {
313
+ const lines = [];
314
+ lines.push(`version: ${config.version}`);
315
+ lines.push(`name: ${config.name}`);
316
+ if (config.description) {
317
+ lines.push(`description: ${config.description}`);
318
+ }
319
+ // Gates
320
+ if (config.gates && Object.keys(config.gates).length > 0) {
321
+ lines.push(`\ngates:`);
322
+ for (const [gateName, gateConfig] of Object.entries(config.gates)) {
323
+ lines.push(` ${gateName}:`);
324
+ if (gateConfig.adapter) {
325
+ lines.push(` adapter: ${gateConfig.adapter}`);
326
+ }
327
+ if (gateConfig.config) {
328
+ lines.push(` config:`);
329
+ this.indentObject(lines, gateConfig.config, 6);
330
+ }
331
+ if (gateConfig.options) {
332
+ lines.push(` options:`);
333
+ this.indentObject(lines, gateConfig.options, 6);
334
+ }
335
+ if (gateConfig.budgets) {
336
+ lines.push(` budgets:`);
337
+ this.indentObject(lines, gateConfig.budgets, 6);
338
+ }
339
+ }
340
+ }
341
+ // Auth
342
+ if (config.auth && config.auth.profiles) {
343
+ lines.push(`\nauth:`);
344
+ lines.push(` profiles:`);
345
+ for (const [profileName, profile] of Object.entries(config.auth.profiles)) {
346
+ lines.push(` ${profileName}:`);
347
+ this.indentObject(lines, profile, 6);
348
+ }
349
+ }
350
+ // Execution
351
+ if (config.execution) {
352
+ lines.push(`\nexecution:`);
353
+ this.indentObject(lines, config.execution, 2);
354
+ }
355
+ return lines.join('\n');
356
+ }
357
+ /**
358
+ * Helper to indent object properties
359
+ */
360
+ indentObject(lines, obj, indent) {
361
+ const spaces = ' '.repeat(indent);
362
+ for (const [key, value] of Object.entries(obj)) {
363
+ if (value === undefined || value === null) {
364
+ continue;
365
+ }
366
+ if (typeof value === 'object' && !Array.isArray(value)) {
367
+ lines.push(`${spaces}${key}:`);
368
+ this.indentObject(lines, value, indent + 2);
369
+ }
370
+ else if (Array.isArray(value)) {
371
+ if (value.length === 0) {
372
+ lines.push(`${spaces}${key}: []`);
373
+ }
374
+ else {
375
+ lines.push(`${spaces}${key}:`);
376
+ for (const item of value) {
377
+ if (typeof item === 'object' && !Array.isArray(item)) {
378
+ lines.push(`${spaces} -`);
379
+ this.indentObject(lines, item, indent + 4);
380
+ }
381
+ else {
382
+ lines.push(`${spaces} - ${JSON.stringify(item)}`);
383
+ }
384
+ }
385
+ }
386
+ }
387
+ else if (typeof value === 'string') {
388
+ lines.push(`${spaces}${key}: ${value}`);
389
+ }
390
+ else {
391
+ lines.push(`${spaces}${key}: ${JSON.stringify(value)}`);
392
+ }
393
+ }
394
+ }
395
+ }
396
+ /**
397
+ * Convenience function to generate pack from API spec
398
+ */
399
+ export function generatePackFromApiSpec(spec, options) {
400
+ const generator = new PackGenerator(options);
401
+ return generator.generateFromApiSpec(spec, options);
402
+ }
403
+ /**
404
+ * Convenience function to generate pack from UI spec
405
+ */
406
+ export function generatePackFromUiSpec(spec, options) {
407
+ const generator = new PackGenerator(options);
408
+ return generator.generateFromUiSpec(spec, options);
409
+ }
410
+ /**
411
+ * Convenience function to generate pack from performance spec
412
+ */
413
+ export function generatePackFromPerfSpec(spec, options) {
414
+ const generator = new PackGenerator(options);
415
+ return generator.generateFromPerfSpec(spec, options);
416
+ }
@@ -0,0 +1,132 @@
1
+ /**
2
+ * QA360 Prompt Builder
3
+ *
4
+ * Constructs effective prompts for LLM test generation.
5
+ * Uses system prompts, few-shot examples, and structured templates.
6
+ */
7
+ import type { TestSpec, GenerationSource } from './types.js';
8
+ /**
9
+ * Prompt builder options
10
+ */
11
+ export interface PromptBuilderOptions {
12
+ /**
13
+ * Include code comments in generated tests
14
+ */
15
+ includeComments?: boolean;
16
+ /**
17
+ * Include detailed assertions
18
+ */
19
+ includeDetailedAssertions?: boolean;
20
+ /**
21
+ * Include retry logic for flaky tests
22
+ */
23
+ includeRetryLogic?: boolean;
24
+ /**
25
+ * Target code style
26
+ */
27
+ codeStyle?: 'clean' | 'verbose' | 'concise';
28
+ /**
29
+ * Few-shot examples to include
30
+ */
31
+ examples?: string[];
32
+ /**
33
+ * Custom system prompt
34
+ */
35
+ systemPrompt?: string;
36
+ }
37
+ /**
38
+ * Built prompt result
39
+ */
40
+ export interface BuiltPrompt {
41
+ system: string;
42
+ user: string;
43
+ estimatedTokens: number;
44
+ }
45
+ /**
46
+ * Prompt Builder class
47
+ */
48
+ export declare class PromptBuilder {
49
+ private readonly options;
50
+ private readonly defaultOptions;
51
+ constructor(options?: PromptBuilderOptions);
52
+ /**
53
+ * Build prompt from generation source
54
+ */
55
+ buildFromSource(source: GenerationSource): Promise<BuiltPrompt>;
56
+ /**
57
+ * Build prompt from OpenAPI/Swagger spec
58
+ */
59
+ buildFromOpenAPI(specPath: string): BuiltPrompt;
60
+ /**
61
+ * Build prompt from HAR file
62
+ */
63
+ buildFromHAR(filePath: string): BuiltPrompt;
64
+ /**
65
+ * Build prompt from URL
66
+ */
67
+ buildFromUrl(url: string): BuiltPrompt;
68
+ /**
69
+ * Build prompt from test spec
70
+ */
71
+ buildFromSpec(spec: TestSpec): BuiltPrompt;
72
+ /**
73
+ * Build prompt from description
74
+ */
75
+ buildFromDescription(description: string): BuiltPrompt;
76
+ /**
77
+ * Build prompt from existing code
78
+ */
79
+ buildFromCode(code: string, language: string): BuiltPrompt;
80
+ /**
81
+ * Build API spec prompt
82
+ */
83
+ private buildApiSpecPrompt;
84
+ /**
85
+ * Build UI spec prompt
86
+ */
87
+ private buildUiSpecPrompt;
88
+ /**
89
+ * Build performance spec prompt
90
+ */
91
+ private buildPerfSpecPrompt;
92
+ /**
93
+ * Build unit test spec prompt
94
+ */
95
+ private buildUnitSpecPrompt;
96
+ /**
97
+ * Get default system prompt
98
+ */
99
+ private getDefaultSystemPrompt;
100
+ /**
101
+ * Get code style instructions
102
+ */
103
+ private getCodeStyleInstructions;
104
+ /**
105
+ * Get few-shot example
106
+ */
107
+ private getFewShotExample;
108
+ /**
109
+ * Get API test example
110
+ */
111
+ private getApiExample;
112
+ /**
113
+ * Get UI test example
114
+ */
115
+ private getUiExample;
116
+ /**
117
+ * Get performance test example
118
+ */
119
+ private getPerfExample;
120
+ /**
121
+ * Get unit test example
122
+ */
123
+ private getUnitExample;
124
+ /**
125
+ * Count approximate tokens
126
+ */
127
+ private countTokens;
128
+ }
129
+ /**
130
+ * Create a prompt builder with default options
131
+ */
132
+ export declare function createPromptBuilder(options?: PromptBuilderOptions): PromptBuilder;