@yasserkhanorg/e2e-agents 0.3.2

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 (221) hide show
  1. package/LICENSE +168 -0
  2. package/README.md +620 -0
  3. package/dist/agent/analysis.d.ts +62 -0
  4. package/dist/agent/analysis.d.ts.map +1 -0
  5. package/dist/agent/analysis.js +292 -0
  6. package/dist/agent/blast_radius.d.ts +4 -0
  7. package/dist/agent/blast_radius.d.ts.map +1 -0
  8. package/dist/agent/blast_radius.js +37 -0
  9. package/dist/agent/cache_utils.d.ts +38 -0
  10. package/dist/agent/cache_utils.d.ts.map +1 -0
  11. package/dist/agent/cache_utils.js +67 -0
  12. package/dist/agent/config.d.ts +148 -0
  13. package/dist/agent/config.d.ts.map +1 -0
  14. package/dist/agent/config.js +640 -0
  15. package/dist/agent/dependency_graph.d.ts +14 -0
  16. package/dist/agent/dependency_graph.d.ts.map +1 -0
  17. package/dist/agent/dependency_graph.js +227 -0
  18. package/dist/agent/feedback.d.ts +55 -0
  19. package/dist/agent/feedback.d.ts.map +1 -0
  20. package/dist/agent/feedback.js +257 -0
  21. package/dist/agent/flags.d.ts +23 -0
  22. package/dist/agent/flags.d.ts.map +1 -0
  23. package/dist/agent/flags.js +171 -0
  24. package/dist/agent/flow_catalog.d.ts +25 -0
  25. package/dist/agent/flow_catalog.d.ts.map +1 -0
  26. package/dist/agent/flow_catalog.js +106 -0
  27. package/dist/agent/flow_mapping.d.ts +10 -0
  28. package/dist/agent/flow_mapping.d.ts.map +1 -0
  29. package/dist/agent/flow_mapping.js +84 -0
  30. package/dist/agent/framework.d.ts +13 -0
  31. package/dist/agent/framework.d.ts.map +1 -0
  32. package/dist/agent/framework.js +149 -0
  33. package/dist/agent/gap_suggestions.d.ts +14 -0
  34. package/dist/agent/gap_suggestions.d.ts.map +1 -0
  35. package/dist/agent/gap_suggestions.js +101 -0
  36. package/dist/agent/generator.d.ts +10 -0
  37. package/dist/agent/generator.d.ts.map +1 -0
  38. package/dist/agent/generator.js +115 -0
  39. package/dist/agent/git.d.ts +11 -0
  40. package/dist/agent/git.d.ts.map +1 -0
  41. package/dist/agent/git.js +90 -0
  42. package/dist/agent/handoff.d.ts +22 -0
  43. package/dist/agent/handoff.d.ts.map +1 -0
  44. package/dist/agent/handoff.js +180 -0
  45. package/dist/agent/impact-analyzer.d.ts +114 -0
  46. package/dist/agent/impact-analyzer.d.ts.map +1 -0
  47. package/dist/agent/impact-analyzer.js +557 -0
  48. package/dist/agent/index.d.ts +21 -0
  49. package/dist/agent/index.d.ts.map +1 -0
  50. package/dist/agent/index.js +38 -0
  51. package/dist/agent/model-router.d.ts +57 -0
  52. package/dist/agent/model-router.d.ts.map +1 -0
  53. package/dist/agent/model-router.js +154 -0
  54. package/dist/agent/operational_insights.d.ts +41 -0
  55. package/dist/agent/operational_insights.d.ts.map +1 -0
  56. package/dist/agent/operational_insights.js +126 -0
  57. package/dist/agent/pipeline.d.ts +23 -0
  58. package/dist/agent/pipeline.d.ts.map +1 -0
  59. package/dist/agent/pipeline.js +609 -0
  60. package/dist/agent/plan.d.ts +91 -0
  61. package/dist/agent/plan.d.ts.map +1 -0
  62. package/dist/agent/plan.js +331 -0
  63. package/dist/agent/playwright_report.d.ts +8 -0
  64. package/dist/agent/playwright_report.d.ts.map +1 -0
  65. package/dist/agent/playwright_report.js +126 -0
  66. package/dist/agent/report-generator.d.ts +24 -0
  67. package/dist/agent/report-generator.d.ts.map +1 -0
  68. package/dist/agent/report-generator.js +250 -0
  69. package/dist/agent/report.d.ts +81 -0
  70. package/dist/agent/report.d.ts.map +1 -0
  71. package/dist/agent/report.js +147 -0
  72. package/dist/agent/runner.d.ts +7 -0
  73. package/dist/agent/runner.d.ts.map +1 -0
  74. package/dist/agent/runner.js +576 -0
  75. package/dist/agent/selectors.d.ts +10 -0
  76. package/dist/agent/selectors.d.ts.map +1 -0
  77. package/dist/agent/selectors.js +75 -0
  78. package/dist/agent/spec-bridge.d.ts +101 -0
  79. package/dist/agent/spec-bridge.d.ts.map +1 -0
  80. package/dist/agent/spec-bridge.js +273 -0
  81. package/dist/agent/spec-builder.d.ts +102 -0
  82. package/dist/agent/spec-builder.d.ts.map +1 -0
  83. package/dist/agent/spec-builder.js +273 -0
  84. package/dist/agent/subsystem_risk.d.ts +23 -0
  85. package/dist/agent/subsystem_risk.d.ts.map +1 -0
  86. package/dist/agent/subsystem_risk.js +207 -0
  87. package/dist/agent/telemetry.d.ts +84 -0
  88. package/dist/agent/telemetry.d.ts.map +1 -0
  89. package/dist/agent/telemetry.js +220 -0
  90. package/dist/agent/test_path.d.ts +2 -0
  91. package/dist/agent/test_path.d.ts.map +1 -0
  92. package/dist/agent/test_path.js +23 -0
  93. package/dist/agent/tests.d.ts +18 -0
  94. package/dist/agent/tests.d.ts.map +1 -0
  95. package/dist/agent/tests.js +106 -0
  96. package/dist/agent/traceability.d.ts +22 -0
  97. package/dist/agent/traceability.d.ts.map +1 -0
  98. package/dist/agent/traceability.js +183 -0
  99. package/dist/agent/traceability_capture.d.ts +18 -0
  100. package/dist/agent/traceability_capture.d.ts.map +1 -0
  101. package/dist/agent/traceability_capture.js +313 -0
  102. package/dist/agent/traceability_ingest.d.ts +21 -0
  103. package/dist/agent/traceability_ingest.d.ts.map +1 -0
  104. package/dist/agent/traceability_ingest.js +237 -0
  105. package/dist/agent/utils.d.ts +13 -0
  106. package/dist/agent/utils.d.ts.map +1 -0
  107. package/dist/agent/utils.js +152 -0
  108. package/dist/agent/validators/selector-validator.d.ts +74 -0
  109. package/dist/agent/validators/selector-validator.d.ts.map +1 -0
  110. package/dist/agent/validators/selector-validator.js +165 -0
  111. package/dist/anthropic_provider.d.ts +65 -0
  112. package/dist/anthropic_provider.d.ts.map +1 -0
  113. package/dist/anthropic_provider.js +332 -0
  114. package/dist/api.d.ts +48 -0
  115. package/dist/api.d.ts.map +1 -0
  116. package/dist/api.js +113 -0
  117. package/dist/base_provider.d.ts +53 -0
  118. package/dist/base_provider.d.ts.map +1 -0
  119. package/dist/base_provider.js +81 -0
  120. package/dist/cli.d.ts +3 -0
  121. package/dist/cli.d.ts.map +1 -0
  122. package/dist/cli.js +843 -0
  123. package/dist/custom_provider.d.ts +20 -0
  124. package/dist/custom_provider.d.ts.map +1 -0
  125. package/dist/custom_provider.js +276 -0
  126. package/dist/e2e-test-gen/index.d.ts +51 -0
  127. package/dist/e2e-test-gen/index.d.ts.map +1 -0
  128. package/dist/e2e-test-gen/index.js +57 -0
  129. package/dist/e2e-test-gen/spec_parser.d.ts +142 -0
  130. package/dist/e2e-test-gen/spec_parser.d.ts.map +1 -0
  131. package/dist/e2e-test-gen/spec_parser.js +786 -0
  132. package/dist/e2e-test-gen/types.d.ts +185 -0
  133. package/dist/e2e-test-gen/types.d.ts.map +1 -0
  134. package/dist/e2e-test-gen/types.js +4 -0
  135. package/dist/esm/agent/analysis.js +287 -0
  136. package/dist/esm/agent/blast_radius.js +34 -0
  137. package/dist/esm/agent/cache_utils.js +63 -0
  138. package/dist/esm/agent/config.js +637 -0
  139. package/dist/esm/agent/dependency_graph.js +224 -0
  140. package/dist/esm/agent/feedback.js +253 -0
  141. package/dist/esm/agent/flags.js +160 -0
  142. package/dist/esm/agent/flow_catalog.js +103 -0
  143. package/dist/esm/agent/flow_mapping.js +81 -0
  144. package/dist/esm/agent/framework.js +145 -0
  145. package/dist/esm/agent/gap_suggestions.js +98 -0
  146. package/dist/esm/agent/generator.js +112 -0
  147. package/dist/esm/agent/git.js +87 -0
  148. package/dist/esm/agent/handoff.js +177 -0
  149. package/dist/esm/agent/impact-analyzer.js +548 -0
  150. package/dist/esm/agent/index.js +22 -0
  151. package/dist/esm/agent/model-router.js +150 -0
  152. package/dist/esm/agent/operational_insights.js +123 -0
  153. package/dist/esm/agent/pipeline.js +605 -0
  154. package/dist/esm/agent/plan.js +324 -0
  155. package/dist/esm/agent/playwright_report.js +123 -0
  156. package/dist/esm/agent/report-generator.js +247 -0
  157. package/dist/esm/agent/report.js +144 -0
  158. package/dist/esm/agent/runner.js +572 -0
  159. package/dist/esm/agent/selectors.js +71 -0
  160. package/dist/esm/agent/spec-bridge.js +267 -0
  161. package/dist/esm/agent/spec-builder.js +267 -0
  162. package/dist/esm/agent/subsystem_risk.js +204 -0
  163. package/dist/esm/agent/telemetry.js +216 -0
  164. package/dist/esm/agent/test_path.js +20 -0
  165. package/dist/esm/agent/tests.js +101 -0
  166. package/dist/esm/agent/traceability.js +180 -0
  167. package/dist/esm/agent/traceability_capture.js +310 -0
  168. package/dist/esm/agent/traceability_ingest.js +234 -0
  169. package/dist/esm/agent/utils.js +138 -0
  170. package/dist/esm/agent/validators/selector-validator.js +160 -0
  171. package/dist/esm/anthropic_provider.js +324 -0
  172. package/dist/esm/api.js +105 -0
  173. package/dist/esm/base_provider.js +77 -0
  174. package/dist/esm/cli.js +841 -0
  175. package/dist/esm/custom_provider.js +272 -0
  176. package/dist/esm/e2e-test-gen/index.js +50 -0
  177. package/dist/esm/e2e-test-gen/spec_parser.js +782 -0
  178. package/dist/esm/e2e-test-gen/types.js +3 -0
  179. package/dist/esm/index.js +16 -0
  180. package/dist/esm/logger.js +89 -0
  181. package/dist/esm/mcp-server.js +465 -0
  182. package/dist/esm/ollama_provider.js +300 -0
  183. package/dist/esm/openai_provider.js +242 -0
  184. package/dist/esm/package.json +3 -0
  185. package/dist/esm/plan-and-test-constants.js +126 -0
  186. package/dist/esm/provider_factory.js +336 -0
  187. package/dist/esm/provider_interface.js +23 -0
  188. package/dist/esm/provider_utils.js +96 -0
  189. package/dist/index.d.ts +31 -0
  190. package/dist/index.d.ts.map +1 -0
  191. package/dist/index.js +41 -0
  192. package/dist/logger.d.ts +23 -0
  193. package/dist/logger.d.ts.map +1 -0
  194. package/dist/logger.js +93 -0
  195. package/dist/mcp-server.d.ts +35 -0
  196. package/dist/mcp-server.d.ts.map +1 -0
  197. package/dist/mcp-server.js +469 -0
  198. package/dist/ollama_provider.d.ts +65 -0
  199. package/dist/ollama_provider.d.ts.map +1 -0
  200. package/dist/ollama_provider.js +308 -0
  201. package/dist/openai_provider.d.ts +23 -0
  202. package/dist/openai_provider.d.ts.map +1 -0
  203. package/dist/openai_provider.js +250 -0
  204. package/dist/plan-and-test-constants.d.ts +110 -0
  205. package/dist/plan-and-test-constants.d.ts.map +1 -0
  206. package/dist/plan-and-test-constants.js +132 -0
  207. package/dist/provider_factory.d.ts +99 -0
  208. package/dist/provider_factory.d.ts.map +1 -0
  209. package/dist/provider_factory.js +341 -0
  210. package/dist/provider_interface.d.ts +358 -0
  211. package/dist/provider_interface.d.ts.map +1 -0
  212. package/dist/provider_interface.js +28 -0
  213. package/dist/provider_utils.d.ts +39 -0
  214. package/dist/provider_utils.d.ts.map +1 -0
  215. package/dist/provider_utils.js +103 -0
  216. package/package.json +101 -0
  217. package/schemas/gap.schema.json +18 -0
  218. package/schemas/impact.schema.json +418 -0
  219. package/schemas/plan.schema.json +285 -0
  220. package/schemas/subsystem-risk-map.schema.json +62 -0
  221. package/schemas/traceability-input.schema.json +122 -0
@@ -0,0 +1,20 @@
1
+ import type { CustomConfig, GenerateOptions, ImageInput, LLMResponse, ProviderCapabilities } from './provider_interface.js';
2
+ import { BaseProvider } from './base_provider.js';
3
+ export declare class CustomProvider extends BaseProvider {
4
+ name: string;
5
+ private config;
6
+ capabilities: ProviderCapabilities;
7
+ constructor(config: CustomConfig);
8
+ generateText(prompt: string, options?: GenerateOptions): Promise<LLMResponse>;
9
+ analyzeImage(images: ImageInput[], prompt: string, options?: GenerateOptions): Promise<LLMResponse>;
10
+ private dispatchRequest;
11
+ private requestOpenAI;
12
+ private requestAnthropic;
13
+ private requestCustom;
14
+ streamText(): AsyncGenerator<string, void, unknown>;
15
+ checkHealth(): Promise<{
16
+ healthy: boolean;
17
+ message: string;
18
+ }>;
19
+ }
20
+ //# sourceMappingURL=custom_provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom_provider.d.ts","sourceRoot":"","sources":["../src/custom_provider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACR,YAAY,EACZ,eAAe,EACf,UAAU,EACV,WAAW,EACX,oBAAoB,EACvB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAC;AA6DhD,qBAAa,cAAe,SAAQ,YAAY;IAC5C,IAAI,SAAY;IAChB,OAAO,CAAC,MAAM,CAAe;IAE7B,YAAY,EAAE,oBAAoB,CAAC;gBAEvB,MAAM,EAAE,YAAY;IAyB1B,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC;IAkC7E,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC;YAyC3F,eAAe;YAiBf,aAAa;YA8Eb,gBAAgB;YA6EhB,aAAa;IAqBpB,UAAU,IAAI,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC;IAKpD,WAAW,IAAI,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAC,CAAC;CAOpE"}
@@ -0,0 +1,276 @@
1
+ "use strict";
2
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
3
+ // See LICENSE.txt for license information.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.CustomProvider = void 0;
6
+ const provider_interface_js_1 = require("./provider_interface.js");
7
+ const provider_utils_js_1 = require("./provider_utils.js");
8
+ const base_provider_js_1 = require("./base_provider.js");
9
+ const logger_js_1 = require("./logger.js");
10
+ function normalizeUrl(baseUrl, pathSuffix) {
11
+ const trimmed = baseUrl.replace(/\/+$/, '');
12
+ if (trimmed.endsWith(pathSuffix)) {
13
+ return trimmed;
14
+ }
15
+ return `${trimmed}${pathSuffix}`;
16
+ }
17
+ async function postJson(url, headers, body, timeoutMs, context) {
18
+ const controller = new AbortController();
19
+ const timer = timeoutMs ? setTimeout(() => controller.abort(), timeoutMs) : undefined;
20
+ try {
21
+ const response = await fetch(url, {
22
+ method: 'POST',
23
+ headers: {
24
+ 'content-type': 'application/json',
25
+ ...headers,
26
+ },
27
+ body: JSON.stringify(body),
28
+ signal: controller.signal,
29
+ });
30
+ if (!response.ok) {
31
+ throw new Error(`HTTP ${response.status}`);
32
+ }
33
+ return (await response.json());
34
+ }
35
+ catch (error) {
36
+ if (error instanceof Error && error.name === 'AbortError') {
37
+ throw new Error(`Request timeout (${context})`);
38
+ }
39
+ throw error;
40
+ }
41
+ finally {
42
+ if (timer) {
43
+ clearTimeout(timer);
44
+ }
45
+ }
46
+ }
47
+ class CustomProvider extends base_provider_js_1.BaseProvider {
48
+ constructor(config) {
49
+ super();
50
+ this.name = 'custom';
51
+ const validation = (0, provider_utils_js_1.validateAndSanitizeUrl)(config.baseUrl);
52
+ if (!validation.valid) {
53
+ throw new Error(`Invalid base URL: ${validation.warning}`);
54
+ }
55
+ if (validation.warning) {
56
+ logger_js_1.logger.warn(`HTTPS required for remote URLs: ${validation.warning}`);
57
+ }
58
+ this.config = config;
59
+ this.capabilities = {
60
+ vision: config.requestFormat !== 'custom',
61
+ streaming: false,
62
+ maxTokens: 0,
63
+ costPer1MInputTokens: 0,
64
+ costPer1MOutputTokens: 0,
65
+ supportsTools: false,
66
+ supportsPromptCaching: false,
67
+ typicalResponseTimeMs: 0,
68
+ };
69
+ }
70
+ async generateText(prompt, options) {
71
+ const startTime = Date.now();
72
+ try {
73
+ if (prompt.length > 10 * 1024 * 1024) {
74
+ throw new Error('Prompt exceeds maximum size (10MB)');
75
+ }
76
+ const response = await this.dispatchRequest(prompt, options);
77
+ const responseTime = Date.now() - startTime;
78
+ const text = response.text;
79
+ const usage = response.usage;
80
+ const cost = response.cost;
81
+ this.updateStats(usage, responseTime, cost);
82
+ return {
83
+ text,
84
+ usage,
85
+ cost,
86
+ metadata: response.metadata,
87
+ };
88
+ }
89
+ catch (error) {
90
+ this.stats.failedRequests++;
91
+ throw new provider_interface_js_1.LLMProviderError((0, provider_utils_js_1.sanitizeErrorMessage)(error, 'generateText'), this.name, undefined, error);
92
+ }
93
+ }
94
+ async analyzeImage(images, prompt, options) {
95
+ if (this.config.requestFormat === 'custom') {
96
+ throw new provider_interface_js_1.UnsupportedCapabilityError(this.name, 'vision');
97
+ }
98
+ const startTime = Date.now();
99
+ try {
100
+ if (images.length === 0 || images.length > 20) {
101
+ throw new Error('Image count must be between 1 and 20');
102
+ }
103
+ if (prompt.length > 10 * 1024 * 1024) {
104
+ throw new Error('Prompt exceeds maximum size (10MB)');
105
+ }
106
+ const response = await this.dispatchRequest(prompt, options, images);
107
+ const responseTime = Date.now() - startTime;
108
+ const text = response.text;
109
+ const usage = response.usage;
110
+ const cost = response.cost;
111
+ this.updateStats(usage, responseTime, cost);
112
+ return {
113
+ text,
114
+ usage,
115
+ cost,
116
+ metadata: response.metadata,
117
+ };
118
+ }
119
+ catch (error) {
120
+ this.stats.failedRequests++;
121
+ throw new provider_interface_js_1.LLMProviderError((0, provider_utils_js_1.sanitizeErrorMessage)(error, 'analyzeImage'), this.name, undefined, error);
122
+ }
123
+ }
124
+ async dispatchRequest(prompt, options, images) {
125
+ switch (this.config.requestFormat) {
126
+ case 'openai':
127
+ return this.requestOpenAI(prompt, options, images);
128
+ case 'anthropic':
129
+ return this.requestAnthropic(prompt, options, images);
130
+ case 'custom':
131
+ return this.requestCustom(prompt, options);
132
+ default:
133
+ throw new Error(`Unsupported request format: ${this.config.requestFormat}`);
134
+ }
135
+ }
136
+ async requestOpenAI(prompt, options, images) {
137
+ const url = normalizeUrl(this.config.baseUrl, '/chat/completions');
138
+ const messages = [];
139
+ if (options?.systemPrompt) {
140
+ messages.push({ role: 'system', content: options.systemPrompt });
141
+ }
142
+ if (images && images.length > 0) {
143
+ const content = [
144
+ { type: 'text', text: prompt },
145
+ ];
146
+ for (const image of images) {
147
+ const mediaType = (image.mimeType || image.mediaType || 'image/png');
148
+ if (!['image/png', 'image/jpeg', 'image/webp'].includes(mediaType)) {
149
+ throw new Error(`Unsupported image type: ${mediaType}`);
150
+ }
151
+ const data = image.data || image.base64 || '';
152
+ if (data.length > 20 * 1024 * 1024) {
153
+ throw new Error('Image data exceeds maximum size (20MB)');
154
+ }
155
+ content.push({
156
+ type: 'image_url',
157
+ image_url: { url: `data:${mediaType};base64,${data}` },
158
+ });
159
+ if (image.description) {
160
+ content.push({ type: 'text', text: `[Image: ${image.description}]` });
161
+ }
162
+ }
163
+ messages.push({ role: 'user', content });
164
+ }
165
+ else {
166
+ messages.push({ role: 'user', content: prompt });
167
+ }
168
+ const body = {
169
+ model: this.config.model,
170
+ messages,
171
+ max_tokens: options?.maxTokens,
172
+ temperature: options?.temperature,
173
+ top_p: options?.topP,
174
+ stop: options?.stopSequences,
175
+ };
176
+ const response = await postJson(url, this.config.auth, body, options?.timeout, 'openai');
177
+ const text = response.choices?.[0]?.message?.content || '';
178
+ const usage = {
179
+ inputTokens: response.usage?.prompt_tokens || 0,
180
+ outputTokens: response.usage?.completion_tokens || 0,
181
+ totalTokens: response.usage?.total_tokens || 0,
182
+ };
183
+ return {
184
+ text,
185
+ usage,
186
+ cost: 0,
187
+ metadata: {
188
+ finishReason: response.choices?.[0]?.finish_reason,
189
+ },
190
+ };
191
+ }
192
+ async requestAnthropic(prompt, options, images) {
193
+ const url = normalizeUrl(this.config.baseUrl, '/messages');
194
+ const content = [
195
+ { type: 'text', text: prompt },
196
+ ];
197
+ if (images && images.length > 0) {
198
+ for (const image of images) {
199
+ const mediaType = (image.mimeType || image.mediaType || 'image/png');
200
+ if (!['image/png', 'image/jpeg', 'image/webp', 'image/gif'].includes(mediaType)) {
201
+ throw new Error(`Unsupported image type: ${mediaType}`);
202
+ }
203
+ const data = image.data || image.base64 || '';
204
+ if (data.length > 20 * 1024 * 1024) {
205
+ throw new Error('Image data exceeds maximum size (20MB)');
206
+ }
207
+ content.push({
208
+ type: 'image',
209
+ source: {
210
+ type: 'base64',
211
+ media_type: mediaType,
212
+ data,
213
+ },
214
+ });
215
+ if (image.description) {
216
+ content.push({ type: 'text', text: `[Image: ${image.description}]` });
217
+ }
218
+ }
219
+ }
220
+ const body = {
221
+ model: this.config.model,
222
+ max_tokens: options?.maxTokens || 4000,
223
+ temperature: options?.temperature,
224
+ top_p: options?.topP,
225
+ stop_sequences: options?.stopSequences,
226
+ system: options?.systemPrompt,
227
+ messages: [
228
+ {
229
+ role: 'user',
230
+ content,
231
+ },
232
+ ],
233
+ };
234
+ const response = await postJson(url, this.config.auth, body, options?.timeout, 'anthropic');
235
+ const text = (response.content || []).map((block) => block.text).join('\n');
236
+ const usage = {
237
+ inputTokens: response.usage?.input_tokens || 0,
238
+ outputTokens: response.usage?.output_tokens || 0,
239
+ totalTokens: (response.usage?.input_tokens || 0) + (response.usage?.output_tokens || 0),
240
+ };
241
+ return {
242
+ text,
243
+ usage,
244
+ cost: 0,
245
+ metadata: {
246
+ stopReason: response.stop_reason,
247
+ },
248
+ };
249
+ }
250
+ async requestCustom(prompt, options) {
251
+ if (!this.config.transformRequest || !this.config.transformResponse) {
252
+ throw new Error('Custom providers require transformRequest and transformResponse');
253
+ }
254
+ const body = this.config.transformRequest(prompt, options);
255
+ const response = await postJson(this.config.baseUrl, this.config.auth, body, options?.timeout, 'custom');
256
+ const transformed = this.config.transformResponse(response);
257
+ return {
258
+ text: transformed.text,
259
+ usage: transformed.usage,
260
+ cost: transformed.cost,
261
+ metadata: transformed.metadata,
262
+ };
263
+ }
264
+ // CustomProvider doesn't support streaming
265
+ async *streamText() {
266
+ throw new Error('Streaming not supported for custom providers');
267
+ }
268
+ // CustomProvider doesn't have built-in health checks
269
+ async checkHealth() {
270
+ return {
271
+ healthy: true,
272
+ message: 'Custom provider configured',
273
+ };
274
+ }
275
+ }
276
+ exports.CustomProvider = CustomProvider;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Autonomous E2E Testing System
3
+ *
4
+ * A specification-driven testing system that bridges PDF/Markdown specs
5
+ * with Playwright's native agents for test planning, generation, and healing.
6
+ *
7
+ * Quick Start:
8
+ * ```typescript
9
+ * import {SpecBridge, createAnthropicBridge} from '@mattermost/playwright-lib/autonomous';
10
+ *
11
+ * // Convert a specification to Playwright-compatible markdown
12
+ * const bridge = createAnthropicBridge(process.env.ANTHROPIC_API_KEY);
13
+ * const result = await bridge.convertToPlaywrightSpecs('spec.pdf', 'specs/');
14
+ *
15
+ * // Then use Playwright agents:
16
+ * // @planner explore http://localhost:8065
17
+ * // @generator create tests from specs/
18
+ * // @healer fix failing tests
19
+ * ```
20
+ *
21
+ * Architecture:
22
+ * - SpecificationParser: Parses PDF/MD/JSON specs into structured format
23
+ * - SpecBridge: Converts specs to Playwright Agent-compatible markdown
24
+ * - LLM Providers: Pluggable AI providers (Anthropic, Ollama, OpenAI)
25
+ *
26
+ * The heavy lifting (test generation, execution, healing) is delegated to
27
+ * Playwright's built-in agents which are production-ready and maintained
28
+ * by the Playwright team.
29
+ */
30
+ export { SpecificationParser } from './spec_parser.js';
31
+ export type { SpecSummary, SpecificationCache } from './spec_parser.js';
32
+ export { LLMProviderFactory } from '../provider_factory.js';
33
+ export { OllamaProvider } from '../ollama_provider.js';
34
+ export { AnthropicProvider } from '../anthropic_provider.js';
35
+ export type { LLMProvider, LLMResponse, GenerateOptions, ImageInput, ProviderCapabilities, ProviderUsageStats, ProviderConfig, OllamaConfig, AnthropicConfig, } from '../provider_interface.js';
36
+ export type { HybridConfig } from '../provider_factory.js';
37
+ export type { FeatureSpecification, BusinessScenario, SpecScreenshot, GeneratedTest, } from './types.js';
38
+ /**
39
+ * Version info
40
+ */
41
+ export declare const VERSION = "2.0.0";
42
+ export declare const SUPPORTED_PLAYWRIGHT_VERSION = "1.56.0";
43
+ /**
44
+ * Feature flags
45
+ */
46
+ export declare const FEATURES: {
47
+ readonly LLM_AGNOSTIC: true;
48
+ readonly SPECIFICATION_DRIVEN: true;
49
+ readonly PLAYWRIGHT_AGENTS: true;
50
+ };
51
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/e2e-test-gen/index.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAGH,OAAO,EAAC,mBAAmB,EAAC,MAAM,kBAAkB,CAAC;AACrD,YAAY,EAAC,WAAW,EAAE,kBAAkB,EAAC,MAAM,kBAAkB,CAAC;AAGtE,OAAO,EAAC,kBAAkB,EAAC,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAC,cAAc,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAC,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AAE3D,YAAY,EACR,WAAW,EACX,WAAW,EACX,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,eAAe,GAClB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EAAC,YAAY,EAAC,MAAM,wBAAwB,CAAC;AAGzD,YAAY,EAER,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EAGd,aAAa,GAChB,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,eAAO,MAAM,OAAO,UAAU,CAAC;AAC/B,eAAO,MAAM,4BAA4B,WAAW,CAAC;AAErD;;GAEG;AACH,eAAO,MAAM,QAAQ;;;;CAIX,CAAC"}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
3
+ // See LICENSE.txt for license information.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.FEATURES = exports.SUPPORTED_PLAYWRIGHT_VERSION = exports.VERSION = exports.AnthropicProvider = exports.OllamaProvider = exports.LLMProviderFactory = exports.SpecificationParser = void 0;
6
+ /**
7
+ * Autonomous E2E Testing System
8
+ *
9
+ * A specification-driven testing system that bridges PDF/Markdown specs
10
+ * with Playwright's native agents for test planning, generation, and healing.
11
+ *
12
+ * Quick Start:
13
+ * ```typescript
14
+ * import {SpecBridge, createAnthropicBridge} from '@mattermost/playwright-lib/autonomous';
15
+ *
16
+ * // Convert a specification to Playwright-compatible markdown
17
+ * const bridge = createAnthropicBridge(process.env.ANTHROPIC_API_KEY);
18
+ * const result = await bridge.convertToPlaywrightSpecs('spec.pdf', 'specs/');
19
+ *
20
+ * // Then use Playwright agents:
21
+ * // @planner explore http://localhost:8065
22
+ * // @generator create tests from specs/
23
+ * // @healer fix failing tests
24
+ * ```
25
+ *
26
+ * Architecture:
27
+ * - SpecificationParser: Parses PDF/MD/JSON specs into structured format
28
+ * - SpecBridge: Converts specs to Playwright Agent-compatible markdown
29
+ * - LLM Providers: Pluggable AI providers (Anthropic, Ollama, OpenAI)
30
+ *
31
+ * The heavy lifting (test generation, execution, healing) is delegated to
32
+ * Playwright's built-in agents which are production-ready and maintained
33
+ * by the Playwright team.
34
+ */
35
+ // Core Components
36
+ var spec_parser_js_1 = require("./spec_parser.js");
37
+ Object.defineProperty(exports, "SpecificationParser", { enumerable: true, get: function () { return spec_parser_js_1.SpecificationParser; } });
38
+ // LLM Providers (re-exported from parent package)
39
+ var provider_factory_js_1 = require("../provider_factory.js");
40
+ Object.defineProperty(exports, "LLMProviderFactory", { enumerable: true, get: function () { return provider_factory_js_1.LLMProviderFactory; } });
41
+ var ollama_provider_js_1 = require("../ollama_provider.js");
42
+ Object.defineProperty(exports, "OllamaProvider", { enumerable: true, get: function () { return ollama_provider_js_1.OllamaProvider; } });
43
+ var anthropic_provider_js_1 = require("../anthropic_provider.js");
44
+ Object.defineProperty(exports, "AnthropicProvider", { enumerable: true, get: function () { return anthropic_provider_js_1.AnthropicProvider; } });
45
+ /**
46
+ * Version info
47
+ */
48
+ exports.VERSION = '2.0.0';
49
+ exports.SUPPORTED_PLAYWRIGHT_VERSION = '1.56.0';
50
+ /**
51
+ * Feature flags
52
+ */
53
+ exports.FEATURES = {
54
+ LLM_AGNOSTIC: true,
55
+ SPECIFICATION_DRIVEN: true,
56
+ PLAYWRIGHT_AGENTS: true,
57
+ };
@@ -0,0 +1,142 @@
1
+ import type { LLMProvider } from '../provider_interface.js';
2
+ import type { FeatureSpecification } from './types.js';
3
+ /**
4
+ * Optional cache interface for PDF parsing results
5
+ * Implementations can provide caching to avoid re-parsing PDFs
6
+ */
7
+ export interface SpecificationCache {
8
+ isSpecificationCached(path: string, hash: string): boolean;
9
+ getCachedSpecifications(path: string, hash: string): FeatureSpecification[];
10
+ saveSpecification(spec: FeatureSpecification): void;
11
+ }
12
+ /**
13
+ * Specification Parser
14
+ *
15
+ * Parses user-provided specification documents to guide autonomous testing.
16
+ * Supports multiple formats:
17
+ * - Markdown (.md) with embedded screenshots and Given-When-Then scenarios
18
+ * - JSON (.json) with structured feature definitions
19
+ * - PDF (.pdf) with text, diagrams, and screenshots extracted via LLM
20
+ * - Plain text focus strings (natural language)
21
+ *
22
+ * Extracts:
23
+ * - Feature name, description, priority
24
+ * - Target URLs to prioritize in crawling
25
+ * - Business scenarios (Given-When-Then)
26
+ * - Acceptance criteria
27
+ * - Reference screenshots for visual comparison
28
+ * - UI mockups and wireframes from PDFs
29
+ *
30
+ * The parsed specifications guide:
31
+ * - Crawler URL prioritization
32
+ * - Test scenario generation
33
+ * - Visual regression comparison
34
+ * - Coverage gap detection
35
+ */
36
+ export declare class SpecificationParser {
37
+ private llmProvider;
38
+ private cache?;
39
+ constructor(llmProvider: LLMProvider, cache?: SpecificationCache);
40
+ /**
41
+ * Parse specification from file or string
42
+ */
43
+ parse(source: string, sourceType?: 'file' | 'string'): Promise<FeatureSpecification[]>;
44
+ /**
45
+ * Parse Markdown specification
46
+ *
47
+ * Expected format:
48
+ * # Feature: Feature Name
49
+ * **Priority**: High
50
+ * **Target URLs**: /path1, /path2
51
+ *
52
+ * ## Description
53
+ * Feature description...
54
+ *
55
+ * ## Business Scenarios
56
+ * ### Scenario 1: Name
57
+ * - **Given**: Precondition
58
+ * - **When**: Action
59
+ * - **Then**: Expected outcome
60
+ *
61
+ * ## Acceptance Criteria
62
+ * - Criterion 1
63
+ * - Criterion 2
64
+ *
65
+ * ## Screenshots
66
+ * ![Description](path/to/image.png)
67
+ */
68
+ private parseMarkdown;
69
+ /**
70
+ * Parse JSON specification
71
+ */
72
+ private parseJSON;
73
+ /**
74
+ * Parse PDF specification using LLM vision
75
+ *
76
+ * PDFs can contain:
77
+ * - Product requirement documents (PRDs)
78
+ * - Feature specifications with screenshots
79
+ * - UI mockups and wireframes
80
+ * - User flow diagrams
81
+ * - Acceptance criteria and test plans
82
+ *
83
+ * The LLM will extract structured information including:
84
+ * - Feature name and description
85
+ * - Business scenarios
86
+ * - Target URLs (inferred from screenshots/mockups)
87
+ * - Acceptance criteria
88
+ * - Screenshots/mockups for visual comparison
89
+ */
90
+ private parsePDF;
91
+ /**
92
+ * Parse natural language focus string using LLM
93
+ */
94
+ private parseFocusString;
95
+ /**
96
+ * Finalize partial spec
97
+ */
98
+ private finalizeSpec;
99
+ /**
100
+ * Finalize partial scenario
101
+ */
102
+ private finalizeScenario;
103
+ /**
104
+ * Generate spec ID from name
105
+ */
106
+ private generateSpecId;
107
+ /**
108
+ * Resolve image path relative to spec file
109
+ */
110
+ private resolveImagePath;
111
+ /**
112
+ * Load screenshot data from files
113
+ */
114
+ private loadScreenshots;
115
+ /**
116
+ * Validate parsed specification
117
+ */
118
+ validateSpec(spec: FeatureSpecification): {
119
+ valid: boolean;
120
+ errors: string[];
121
+ };
122
+ /**
123
+ * Get spec coverage summary
124
+ */
125
+ getSpecSummary(spec: FeatureSpecification): SpecSummary;
126
+ }
127
+ /**
128
+ * Specification summary
129
+ */
130
+ export interface SpecSummary {
131
+ id: string;
132
+ name: string;
133
+ priority: string;
134
+ targetUrlCount: number;
135
+ scenarioCount: number;
136
+ mustHaveScenarios: number;
137
+ shouldHaveScenarios: number;
138
+ niceToHaveScenarios: number;
139
+ acceptanceCriteriaCount: number;
140
+ hasScreenshots: boolean;
141
+ }
142
+ //# sourceMappingURL=spec_parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec_parser.d.ts","sourceRoot":"","sources":["../../src/e2e-test-gen/spec_parser.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,0BAA0B,CAAC;AAE1D,OAAO,KAAK,EAAmB,oBAAoB,EAAiB,MAAM,YAAY,CAAC;AAEvF;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IAC/B,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3D,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,oBAAoB,EAAE,CAAC;IAC5E,iBAAiB,CAAC,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAAC;CACvD;AASD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,mBAAmB;IAC5B,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,KAAK,CAAC,CAAqB;gBAEvB,WAAW,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE,kBAAkB;IAKhE;;OAEG;IACG,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,GAAE,MAAM,GAAG,QAAiB,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;IA6BpG;;;;;;;;;;;;;;;;;;;;;;;OAuBG;YACW,aAAa;IAyI3B;;OAEG;IACH,OAAO,CAAC,SAAS;IAgFjB;;;;;;;;;;;;;;;;OAgBG;YACW,QAAQ;IA8TtB;;OAEG;YACW,gBAAgB;IA8E9B;;OAEG;IACH,OAAO,CAAC,YAAY;IAcpB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAUxB;;OAEG;IACH,OAAO,CAAC,cAAc;IAOtB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAcxB;;OAEG;YACW,eAAe;IAmB7B;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,oBAAoB,GAAG;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAC;IAwB5E;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,oBAAoB,GAAG,WAAW;CAc1D;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,uBAAuB,EAAE,MAAM,CAAC;IAChC,cAAc,EAAE,OAAO,CAAC;CAC3B"}