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,117 @@
1
+ /**
2
+ * QA360 Test Optimizer
3
+ *
4
+ * Optimizes generated tests for better quality and maintainability.
5
+ * Removes redundancy, improves assertions, and enhances performance.
6
+ */
7
+ import type { GeneratedTest } from './types.js';
8
+ /**
9
+ * Optimization options
10
+ */
11
+ export interface OptimizationOptions {
12
+ /**
13
+ * Remove duplicate tests
14
+ */
15
+ removeDuplicates?: boolean;
16
+ /**
17
+ * Merge similar tests
18
+ */
19
+ mergeSimilarTests?: boolean;
20
+ /**
21
+ * Improve assertions
22
+ */
23
+ improveAssertions?: boolean;
24
+ /**
25
+ * Add performance optimizations
26
+ */
27
+ addPerformanceOptimizations?: boolean;
28
+ /**
29
+ * Reduce test flakiness
30
+ */
31
+ reduceFlakiness?: boolean;
32
+ /**
33
+ * Target maximum test count
34
+ */
35
+ maxTestCount?: number;
36
+ }
37
+ /**
38
+ * Optimization result
39
+ */
40
+ export interface OptimizationResult {
41
+ optimized: GeneratedTest[];
42
+ removed: number;
43
+ merged: number;
44
+ improvements: string[];
45
+ }
46
+ /**
47
+ * Test Optimizer class
48
+ */
49
+ export declare class TestOptimizer {
50
+ private readonly options;
51
+ private readonly defaultOptions;
52
+ constructor(options?: OptimizationOptions);
53
+ /**
54
+ * Optimize generated tests
55
+ */
56
+ optimize(tests: GeneratedTest[]): OptimizationResult;
57
+ /**
58
+ * Remove duplicate tests
59
+ */
60
+ private removeDuplicateTests;
61
+ /**
62
+ * Merge similar test cases
63
+ */
64
+ private mergeSimilarTestCases;
65
+ /**
66
+ * Improve test assertions
67
+ */
68
+ private improveTestAssertions;
69
+ /**
70
+ * Add performance improvements
71
+ */
72
+ private addPerformanceImprovements;
73
+ /**
74
+ * Reduce test flakiness
75
+ */
76
+ private reduceTestFlakiness;
77
+ /**
78
+ * Prioritize tests by importance
79
+ */
80
+ private prioritizeTests;
81
+ /**
82
+ * Create test signature for deduplication
83
+ */
84
+ private createTestSignature;
85
+ /**
86
+ * Calculate similarity between two tests
87
+ */
88
+ private calculateSimilarity;
89
+ /**
90
+ * Merge multiple tests into one
91
+ */
92
+ private mergeTests;
93
+ /**
94
+ * Extract test cases from code
95
+ */
96
+ private extractTestCases;
97
+ /**
98
+ * Enhance assertions in code
99
+ */
100
+ private enhanceAssertions;
101
+ /**
102
+ * Optimize performance
103
+ */
104
+ private optimizePerformance;
105
+ /**
106
+ * Add stability improvements
107
+ */
108
+ private addStabilityImprovements;
109
+ /**
110
+ * Get optimization suggestions for a test
111
+ */
112
+ getSuggestions(test: GeneratedTest): string[];
113
+ }
114
+ /**
115
+ * Create optimizer with default config
116
+ */
117
+ export declare function createOptimizer(options?: OptimizationOptions): TestOptimizer;
@@ -0,0 +1,328 @@
1
+ /**
2
+ * QA360 Test Optimizer
3
+ *
4
+ * Optimizes generated tests for better quality and maintainability.
5
+ * Removes redundancy, improves assertions, and enhances performance.
6
+ */
7
+ /**
8
+ * Test Optimizer class
9
+ */
10
+ export class TestOptimizer {
11
+ options;
12
+ defaultOptions = {
13
+ removeDuplicates: true,
14
+ mergeSimilarTests: true,
15
+ improveAssertions: true,
16
+ addPerformanceOptimizations: true,
17
+ reduceFlakiness: true,
18
+ maxTestCount: 100,
19
+ };
20
+ constructor(options = {}) {
21
+ this.options = { ...this.defaultOptions, ...options };
22
+ }
23
+ /**
24
+ * Optimize generated tests
25
+ */
26
+ optimize(tests) {
27
+ let optimized = [...tests];
28
+ const improvements = [];
29
+ let removed = 0;
30
+ let merged = 0;
31
+ // Remove duplicates
32
+ if (this.options.removeDuplicates) {
33
+ const before = optimized.length;
34
+ optimized = this.removeDuplicateTests(optimized);
35
+ removed = before - optimized.length;
36
+ if (removed > 0) {
37
+ improvements.push(`Removed ${removed} duplicate test(s)`);
38
+ }
39
+ }
40
+ // Merge similar tests
41
+ if (this.options.mergeSimilarTests) {
42
+ const before = optimized.length;
43
+ optimized = this.mergeSimilarTestCases(optimized);
44
+ merged = before - optimized.length;
45
+ if (merged > 0) {
46
+ improvements.push(`Merged ${merged} similar test(s)`);
47
+ }
48
+ }
49
+ // Improve assertions
50
+ if (this.options.improveAssertions) {
51
+ optimized = this.improveTestAssertions(optimized);
52
+ improvements.push('Improved assertions quality');
53
+ }
54
+ // Add performance optimizations
55
+ if (this.options.addPerformanceOptimizations) {
56
+ optimized = this.addPerformanceImprovements(optimized);
57
+ improvements.push('Added performance optimizations');
58
+ }
59
+ // Reduce flakiness
60
+ if (this.options.reduceFlakiness) {
61
+ optimized = this.reduceTestFlakiness(optimized);
62
+ improvements.push('Reduced test flakiness');
63
+ }
64
+ // Limit test count
65
+ if (this.options.maxTestCount && optimized.length > this.options.maxTestCount) {
66
+ const before = optimized.length;
67
+ optimized = this.prioritizeTests(optimized).slice(0, this.options.maxTestCount);
68
+ improvements.push(`Prioritized and kept ${this.options.maxTestCount} most important tests (${before - this.options.maxTestCount} removed)`);
69
+ }
70
+ return {
71
+ optimized,
72
+ removed,
73
+ merged,
74
+ improvements,
75
+ };
76
+ }
77
+ /**
78
+ * Remove duplicate tests
79
+ */
80
+ removeDuplicateTests(tests) {
81
+ const seen = new Set();
82
+ const unique = [];
83
+ for (const test of tests) {
84
+ // Create a signature based on test content
85
+ const signature = this.createTestSignature(test);
86
+ if (!seen.has(signature)) {
87
+ seen.add(signature);
88
+ unique.push(test);
89
+ }
90
+ }
91
+ return unique;
92
+ }
93
+ /**
94
+ * Merge similar test cases
95
+ */
96
+ mergeSimilarTestCases(tests) {
97
+ const merged = [];
98
+ const used = new Set();
99
+ for (let i = 0; i < tests.length; i++) {
100
+ if (used.has(i))
101
+ continue;
102
+ const current = tests[i];
103
+ const similar = [current];
104
+ // Find similar tests
105
+ for (let j = i + 1; j < tests.length; j++) {
106
+ if (used.has(j))
107
+ continue;
108
+ const similarity = this.calculateSimilarity(current, tests[j]);
109
+ if (similarity.score > 0.7) {
110
+ similar.push(tests[j]);
111
+ used.add(j);
112
+ }
113
+ }
114
+ // Merge similar tests or keep as-is
115
+ if (similar.length > 1) {
116
+ merged.push(this.mergeTests(similar));
117
+ }
118
+ else {
119
+ merged.push(current);
120
+ }
121
+ used.add(i);
122
+ }
123
+ return merged;
124
+ }
125
+ /**
126
+ * Improve test assertions
127
+ */
128
+ improveTestAssertions(tests) {
129
+ return tests.map(test => ({
130
+ ...test,
131
+ code: this.enhanceAssertions(test.code),
132
+ }));
133
+ }
134
+ /**
135
+ * Add performance improvements
136
+ */
137
+ addPerformanceImprovements(tests) {
138
+ return tests.map(test => ({
139
+ ...test,
140
+ code: this.optimizePerformance(test.code, test.framework),
141
+ }));
142
+ }
143
+ /**
144
+ * Reduce test flakiness
145
+ */
146
+ reduceTestFlakiness(tests) {
147
+ return tests.map(test => ({
148
+ ...test,
149
+ code: this.addStabilityImprovements(test.code, test.framework),
150
+ }));
151
+ }
152
+ /**
153
+ * Prioritize tests by importance
154
+ */
155
+ prioritizeTests(tests) {
156
+ return tests.sort((a, b) => {
157
+ // Prefer tests with more assertions
158
+ const aAssertions = a.summary.assertionCount || 0;
159
+ const bAssertions = b.summary.assertionCount || 0;
160
+ if (aAssertions !== bAssertions) {
161
+ return bAssertions - aAssertions;
162
+ }
163
+ // Then prefer shorter tests (faster)
164
+ const aLines = a.summary.lines;
165
+ const bLines = b.summary.lines;
166
+ return aLines - bLines;
167
+ });
168
+ }
169
+ /**
170
+ * Create test signature for deduplication
171
+ */
172
+ createTestSignature(test) {
173
+ // Normalize code for comparison
174
+ const normalized = test.code
175
+ .replace(/\s+/g, ' ')
176
+ .replace(/\/\/.*$/gm, '') // Remove comments
177
+ .toLowerCase()
178
+ .trim();
179
+ // Simple hash of content
180
+ let hash = 0;
181
+ for (let i = 0; i < normalized.length; i++) {
182
+ const char = normalized.charCodeAt(i);
183
+ hash = ((hash << 5) - hash) + char;
184
+ hash = hash & hash; // Convert to 32-bit integer
185
+ }
186
+ return `${test.name}-${Math.abs(hash)}`;
187
+ }
188
+ /**
189
+ * Calculate similarity between two tests
190
+ */
191
+ calculateSimilarity(test1, test2) {
192
+ // Check framework match
193
+ if (test1.framework !== test2.framework) {
194
+ return { test1, test2, score: 0 };
195
+ }
196
+ // Compare structure
197
+ const words1 = new Set(test1.code.toLowerCase().split(/\W+/));
198
+ const words2 = new Set(test2.code.toLowerCase().split(/\W+/));
199
+ let intersection = 0;
200
+ for (const word of words1) {
201
+ if (words2.has(word) && word.length > 4) { // Only significant words
202
+ intersection++;
203
+ }
204
+ }
205
+ const union = new Set([...words1, ...words2]).size;
206
+ const score = union > 0 ? intersection / union : 0;
207
+ return { test1, test2, score };
208
+ }
209
+ /**
210
+ * Merge multiple tests into one
211
+ */
212
+ mergeTests(tests) {
213
+ const base = tests[0];
214
+ const mergedName = `${base.name} (merged ${tests.length})`;
215
+ // Combine test code (simplified)
216
+ let mergedCode = base.code;
217
+ // Extract test cases from each and combine them
218
+ for (const test of tests.slice(1)) {
219
+ const testCases = this.extractTestCases(test.code);
220
+ for (const testCase of testCases) {
221
+ mergedCode += '\n\n' + testCase;
222
+ }
223
+ }
224
+ return {
225
+ ...base,
226
+ name: mergedName,
227
+ code: mergedCode,
228
+ summary: {
229
+ lines: mergedCode.split('\n').length,
230
+ testCount: tests.reduce((sum, t) => sum + (t.summary.testCount || 0), 0),
231
+ assertionCount: tests.reduce((sum, t) => sum + (t.summary.assertionCount || 0), 0),
232
+ },
233
+ };
234
+ }
235
+ /**
236
+ * Extract test cases from code
237
+ */
238
+ extractTestCases(code) {
239
+ const cases = [];
240
+ // Match test() or it() blocks
241
+ const testRegex = /\b(test|it)\s*\(\s*['"]([^'"]+)['"][\s\S]*?\n\s*\}\s*\)/g;
242
+ let match;
243
+ while ((match = testRegex.exec(code)) !== null) {
244
+ cases.push(match[0]);
245
+ }
246
+ return cases;
247
+ }
248
+ /**
249
+ * Enhance assertions in code
250
+ */
251
+ enhanceAssertions(code) {
252
+ let enhanced = code;
253
+ // Add status code checks for API tests
254
+ enhanced = enhanced.replace(/const response = await fetch\([^)]+\);\s*$/gm, '$&\n expect(response.status).toBeGreaterThanOrEqual(200);\n expect(response.status).toBeLessThan(300);');
255
+ // Add non-empty assertions for array responses
256
+ enhanced = enhanced.replace(/const data = await response\.json\(\);\s*$/gm, '$&\n expect(data).toBeDefined();');
257
+ // Add timeout for slow operations
258
+ enhanced = enhanced.replace(/\bwaitForURL\(/g, 'waitForURL(');
259
+ return enhanced;
260
+ }
261
+ /**
262
+ * Optimize performance
263
+ */
264
+ optimizePerformance(code, framework) {
265
+ let optimized = code;
266
+ if (framework === 'playwright') {
267
+ // Add reuse of browser contexts where possible
268
+ optimized = optimized.replace(/test\.describe\(/g, 'test.describe.serial(');
269
+ // Suggest parallel test execution
270
+ if (!optimized.includes('test.describe.configure')) {
271
+ optimized = 'test.describe.configure({ mode: \'parallel\' });\n\n' + optimized;
272
+ }
273
+ }
274
+ // Remove unnecessary waits
275
+ optimized = optimized.replace(/\bpage\.waitForTimeout\(\d+\)/g, '// waitForTimeout removed - use explicit waits instead');
276
+ return optimized;
277
+ }
278
+ /**
279
+ * Add stability improvements
280
+ */
281
+ addStabilityImprovements(code, framework) {
282
+ let stable = code;
283
+ if (framework === 'playwright') {
284
+ // Replace waitFor with waitForSelector for more reliable waits
285
+ stable = stable.replace(/\bwaitFor\(/g, 'waitForSelector(');
286
+ // Add explicit waits for navigation
287
+ stable = stable.replace(/(\.click\([^)]+\))(?!.*waitFor)/g, '$1\n await page.waitForLoadState(\'networkidle\');');
288
+ }
289
+ // Add retry logic for API tests
290
+ if (framework === 'playwright' && (code.includes('fetch') || code.includes('axios'))) {
291
+ stable = stable.replace(/test\s*\(\s*['"]([^'"]+)['"]\s*,\s*async\s+/g, 'test(\'$1 (with retry)\', async ');
292
+ }
293
+ return stable;
294
+ }
295
+ /**
296
+ * Get optimization suggestions for a test
297
+ */
298
+ getSuggestions(test) {
299
+ const suggestions = [];
300
+ // Check for missing assertions
301
+ if ((test.summary.assertionCount || 0) < (test.summary.testCount || 1)) {
302
+ suggestions.push('Consider adding more assertions for better coverage');
303
+ }
304
+ // Check for long tests
305
+ if (test.summary.lines > 200) {
306
+ suggestions.push('Test is very long - consider splitting into smaller tests');
307
+ }
308
+ // Check for console.log
309
+ if (test.code.includes('console.log')) {
310
+ suggestions.push('Remove console.log statements - use assertions instead');
311
+ }
312
+ // Check for hardcoded values
313
+ if (test.code.includes('123456') || test.code.includes('test@test')) {
314
+ suggestions.push('Use test fixtures instead of hardcoded values');
315
+ }
316
+ // Check for missing error handling
317
+ if (!test.code.includes('try') && !test.code.includes('catch')) {
318
+ suggestions.push('Consider adding error handling for robustness');
319
+ }
320
+ return suggestions;
321
+ }
322
+ }
323
+ /**
324
+ * Create optimizer with default config
325
+ */
326
+ export function createOptimizer(options) {
327
+ return new TestOptimizer(options);
328
+ }
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Types for AI Test Generation
3
+ */
4
+ /**
5
+ * Base test specification
6
+ */
7
+ export interface TestSpec {
8
+ type: 'api' | 'ui' | 'perf' | 'unit';
9
+ name: string;
10
+ description?: string;
11
+ tags?: string[];
12
+ }
13
+ /**
14
+ * API test specification
15
+ */
16
+ export interface ApiTestSpec extends TestSpec {
17
+ type: 'api';
18
+ baseUrl: string;
19
+ endpoints: ApiEndpoint[];
20
+ auth?: AuthSpec;
21
+ headers?: Record<string, string>;
22
+ }
23
+ /**
24
+ * API endpoint definition
25
+ */
26
+ export interface ApiEndpoint {
27
+ method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
28
+ path: string;
29
+ description?: string;
30
+ headers?: Record<string, string>;
31
+ body?: unknown;
32
+ queryParams?: Record<string, string>;
33
+ expectations?: ApiExpectation[];
34
+ }
35
+ /**
36
+ * API expectations
37
+ */
38
+ export interface ApiExpectation {
39
+ status?: number | number[];
40
+ responseTime?: string;
41
+ hasBody?: boolean;
42
+ schema?: Record<string, unknown>;
43
+ contains?: string[];
44
+ }
45
+ /**
46
+ * UI test specification
47
+ */
48
+ export interface UiTestSpec extends TestSpec {
49
+ type: 'ui';
50
+ baseUrl: string;
51
+ pages: PageSpec[];
52
+ auth?: AuthSpec;
53
+ viewport?: {
54
+ width: number;
55
+ height: number;
56
+ };
57
+ }
58
+ /**
59
+ * Page specification for UI tests
60
+ */
61
+ export interface PageSpec {
62
+ name: string;
63
+ url: string;
64
+ actions: PageAction[];
65
+ assertions?: Assertion[];
66
+ }
67
+ /**
68
+ * Page action
69
+ */
70
+ export interface PageAction {
71
+ type: 'goto' | 'click' | 'fill' | 'select' | 'wait' | 'hover' | 'screenshot' | 'type' | 'check' | 'uncheck';
72
+ selector?: string;
73
+ value?: string;
74
+ timeout?: number;
75
+ options?: Record<string, unknown>;
76
+ }
77
+ /**
78
+ * Assertion for UI tests
79
+ */
80
+ export interface Assertion {
81
+ type: 'url' | 'title' | 'visible' | 'text' | 'attribute' | 'count';
82
+ selector?: string;
83
+ expected: string | number | boolean;
84
+ operator?: 'equals' | 'contains' | 'matches' | 'greaterThan' | 'lessThan';
85
+ }
86
+ /**
87
+ * Performance test specification
88
+ */
89
+ export interface PerfTestSpec extends TestSpec {
90
+ type: 'perf';
91
+ baseUrl: string;
92
+ scenarios: PerfScenario[];
93
+ options?: PerfOptions;
94
+ }
95
+ /**
96
+ * Performance scenario
97
+ */
98
+ export interface PerfScenario {
99
+ name: string;
100
+ weight?: number;
101
+ requests: PerfRequest[];
102
+ thinkTime?: number;
103
+ }
104
+ /**
105
+ * Performance request
106
+ */
107
+ export interface PerfRequest {
108
+ method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
109
+ path: string;
110
+ headers?: Record<string, string>;
111
+ body?: unknown;
112
+ timeout?: number;
113
+ }
114
+ /**
115
+ * Performance test options
116
+ */
117
+ export interface PerfOptions {
118
+ duration?: string;
119
+ rate?: number;
120
+ vus?: number;
121
+ maxVus?: number;
122
+ thresholds?: PerfThreshold[];
123
+ }
124
+ /**
125
+ * Performance thresholds
126
+ */
127
+ export interface PerfThreshold {
128
+ metric: 'http_req_duration' | 'http_req_failed' | 'checks';
129
+ condition: string;
130
+ }
131
+ /**
132
+ * Unit test specification
133
+ */
134
+ export interface UnitTestSpec extends TestSpec {
135
+ type: 'unit';
136
+ source: {
137
+ language: 'typescript' | 'javascript' | 'python' | 'go' | 'rust';
138
+ filePath: string;
139
+ code?: string;
140
+ exports?: string[];
141
+ };
142
+ framework?: 'vitest' | 'jest' | 'pytest' | 'go test';
143
+ }
144
+ /**
145
+ * Authentication specification
146
+ */
147
+ export interface AuthSpec {
148
+ type: 'none' | 'bearer' | 'basic' | 'api_key' | 'oauth2' | 'jwt';
149
+ config?: Record<string, unknown>;
150
+ }
151
+ /**
152
+ * Generation context
153
+ */
154
+ export interface GenerationContext {
155
+ projectName: string;
156
+ framework: 'playwright' | 'k6' | 'vitest' | 'jest';
157
+ language: 'typescript' | 'javascript' | 'go';
158
+ outputDir?: string;
159
+ options?: GenerationOptions;
160
+ }
161
+ /**
162
+ * Generation options
163
+ */
164
+ export interface GenerationOptions {
165
+ includeComments?: boolean;
166
+ includeAssertions?: boolean;
167
+ includeRetryLogic?: boolean;
168
+ optimize?: boolean;
169
+ targetCoverage?: number;
170
+ maxTests?: number;
171
+ }
172
+ /**
173
+ * Generated test result
174
+ */
175
+ export interface GeneratedTest {
176
+ name: string;
177
+ code: string;
178
+ language: string;
179
+ framework: string;
180
+ filePath: string;
181
+ summary: {
182
+ lines: number;
183
+ testCount: number;
184
+ assertionCount?: number;
185
+ };
186
+ metadata?: {
187
+ generatedAt: string;
188
+ model: string;
189
+ tokensUsed: number;
190
+ };
191
+ }
192
+ /**
193
+ * Source for test generation
194
+ */
195
+ export type GenerationSource = {
196
+ type: 'openapi';
197
+ urlOrPath: string;
198
+ } | {
199
+ type: 'har';
200
+ filePath: string;
201
+ } | {
202
+ type: 'url';
203
+ url: string;
204
+ } | {
205
+ type: 'spec';
206
+ spec: TestSpec;
207
+ } | {
208
+ type: 'description';
209
+ description: string;
210
+ } | {
211
+ type: 'code';
212
+ code: string;
213
+ language: string;
214
+ };
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Types for AI Test Generation
3
+ */
4
+ export {};
@@ -60,14 +60,36 @@ export declare class QA360Core {
60
60
  export declare const VERSION = "0.9.0-core";
61
61
  export * from './proof/index.js';
62
62
  export { EvidenceVault } from './vault/index.js';
63
- export type { RunRecord, GateRecord, FindingRecord } from './vault/index.js';
63
+ export type { RunRecord, GateRecord, FindingRecord, FlakinessRecord, FlakinessPatternRecord, QuarantineRecord } from './vault/index.js';
64
64
  export { SecurityRedactor } from './security/redactor.js';
65
65
  export { SecretsManager } from './secrets/manager.js';
66
66
  export { SecretsCrypto } from './secrets/crypto.js';
67
67
  export { PackValidator } from './pack/validator.js';
68
68
  export { PackMigrator } from './pack/migrator.js';
69
69
  export type { PackConfigV1 } from './types/pack-v1.js';
70
+ export * from './ai/index.js';
71
+ export * from './discoverer/index.js';
72
+ export * from './types/pack-v2.js';
73
+ export type { PackConfigV2, AuthConfigV2, AuthProfile, AuthTypeV2, AuthCacheConfig, GateConfigV2, GateBudgets, GateOptions, HooksConfig, Hook, ExecutionConfigV2, ResourceLimits, SecurityBudgets, PerformanceTargets } from './types/pack-v2.js';
74
+ export * from './pack-v2/index.js';
75
+ export { PackLoaderV2, PackValidatorV2, PackLoadResult } from './pack-v2/index.js';
76
+ export type { PackMigrationResultV2, ValidationError } from './pack-v2/index.js';
77
+ export * from './auth/index.js';
78
+ export * from './generation/index.js';
70
79
  export { QA360Server } from './serve/server.js';
71
80
  export type { ServeConfig } from './serve/server.js';
72
81
  export { Phase3Runner } from './runner/phase3-runner.js';
73
82
  export type { Phase3RunnerOptions, Phase3RunResult, GateResult } from './runner/phase3-runner.js';
83
+ export { PlaywrightNativeApiAdapter, createPlaywrightNativeApiAdapter } from './adapters/playwright-native-api.js';
84
+ export type { NativeApiTestConfig, NativeApiSmokeResult } from './adapters/playwright-native-api.js';
85
+ export * from './repair/index.js';
86
+ export * from './tui/index.js';
87
+ export * from './dashboard/index.js';
88
+ export * from './flakiness/index.js';
89
+ export * from './retry/index.js';
90
+ export * from './cache/index.js';
91
+ export * from './watch/index.js';
92
+ export * from './self-healing/index.js';
93
+ export * from './coverage/index.js';
94
+ export * from './slo/index.js';
95
+ export * from './regression/index.js';