@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,152 @@
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.hasGlobChars = hasGlobChars;
6
+ exports.globToRegExp = globToRegExp;
7
+ exports.matchGlob = matchGlob;
8
+ exports.safeReadTextFile = safeReadTextFile;
9
+ exports.normalizePath = normalizePath;
10
+ exports.toRelativePosix = toRelativePosix;
11
+ exports.isPathWithinRoot = isPathWithinRoot;
12
+ exports.fileExtension = fileExtension;
13
+ exports.baseNameWithoutExt = baseNameWithoutExt;
14
+ exports.tokenize = tokenize;
15
+ exports.uniqueTokens = uniqueTokens;
16
+ exports.titleCase = titleCase;
17
+ const fs_1 = require("fs");
18
+ const path_1 = require("path");
19
+ const MAX_READ_BYTES = 1024 * 1024; // 1MB
20
+ const STOP_WORDS = new Set([
21
+ 'index',
22
+ 'component',
23
+ 'components',
24
+ 'page',
25
+ 'pages',
26
+ 'screen',
27
+ 'screens',
28
+ 'view',
29
+ 'views',
30
+ 'route',
31
+ 'routes',
32
+ 'feature',
33
+ 'features',
34
+ 'module',
35
+ 'modules',
36
+ 'flow',
37
+ 'flows',
38
+ 'test',
39
+ 'tests',
40
+ 'spec',
41
+ 'specs',
42
+ 'hooks',
43
+ 'hook',
44
+ 'context',
45
+ 'state',
46
+ 'store',
47
+ ]);
48
+ const GLOB_CHARS = /[*?[\]{}()!]/;
49
+ function hasGlobChars(value) {
50
+ return GLOB_CHARS.test(value);
51
+ }
52
+ function globToRegExp(pattern) {
53
+ const normalized = normalizePath(pattern);
54
+ let regex = '^';
55
+ let i = 0;
56
+ while (i < normalized.length) {
57
+ const char = normalized[i];
58
+ if (char === '*') {
59
+ const next = normalized[i + 1];
60
+ if (next === '*') {
61
+ regex += '.*';
62
+ i += 2;
63
+ continue;
64
+ }
65
+ regex += '[^/]*';
66
+ i += 1;
67
+ continue;
68
+ }
69
+ if (char === '?') {
70
+ regex += '[^/]';
71
+ i += 1;
72
+ continue;
73
+ }
74
+ if ('\\.[]{}()+-^$|'.includes(char)) {
75
+ regex += `\\${char}`;
76
+ }
77
+ else {
78
+ regex += char;
79
+ }
80
+ i += 1;
81
+ }
82
+ regex += '$';
83
+ return new RegExp(regex);
84
+ }
85
+ function matchGlob(pathValue, pattern) {
86
+ const normalizedPath = normalizePath(pathValue);
87
+ const normalizedPattern = normalizePath(pattern);
88
+ if (!hasGlobChars(normalizedPattern)) {
89
+ if (normalizedPattern.endsWith('/')) {
90
+ return normalizedPath.startsWith(normalizedPattern);
91
+ }
92
+ return normalizedPath === normalizedPattern || normalizedPath.startsWith(`${normalizedPattern}/`);
93
+ }
94
+ const regex = globToRegExp(normalizedPattern);
95
+ return regex.test(normalizedPath);
96
+ }
97
+ function safeReadTextFile(path) {
98
+ try {
99
+ const stats = (0, fs_1.statSync)(path);
100
+ if (stats.size > MAX_READ_BYTES) {
101
+ return null;
102
+ }
103
+ return (0, fs_1.readFileSync)(path, 'utf-8');
104
+ }
105
+ catch {
106
+ return null;
107
+ }
108
+ }
109
+ function normalizePath(pathValue) {
110
+ return pathValue.split('\\').join('/');
111
+ }
112
+ function toRelativePosix(root, filePath) {
113
+ const relative = path_1.posix.relative(normalizePath(root), normalizePath(filePath));
114
+ return relative.startsWith('../') ? normalizePath(filePath) : relative;
115
+ }
116
+ function isPathWithinRoot(root, target) {
117
+ const rootAbs = (0, path_1.resolve)(root);
118
+ const targetAbs = (0, path_1.resolve)(target);
119
+ const rel = (0, path_1.relative)(rootAbs, targetAbs);
120
+ return rel === '' || (!rel.startsWith('..') && !rel.includes(`..${path_1.posix.sep}`) && !rel.includes('..\\'));
121
+ }
122
+ function fileExtension(pathValue) {
123
+ return (0, path_1.extname)(pathValue).replace('.', '').toLowerCase();
124
+ }
125
+ function baseNameWithoutExt(pathValue) {
126
+ const base = (0, path_1.basename)(pathValue);
127
+ const ext = (0, path_1.extname)(base);
128
+ return ext ? base.slice(0, -ext.length) : base;
129
+ }
130
+ function splitCamelCase(value) {
131
+ return value.replace(/([a-z])([A-Z])/g, '$1 $2');
132
+ }
133
+ function tokenize(value) {
134
+ const normalized = splitCamelCase(value)
135
+ .replace(/[_\-.]/g, ' ')
136
+ .replace(/[^a-zA-Z0-9\s]/g, ' ')
137
+ .toLowerCase();
138
+ return normalized
139
+ .split(/\s+/)
140
+ .map((token) => token.trim())
141
+ .filter((token) => token.length > 2 && !STOP_WORDS.has(token));
142
+ }
143
+ function uniqueTokens(tokens) {
144
+ return Array.from(new Set(tokens.filter(Boolean)));
145
+ }
146
+ function titleCase(value) {
147
+ return value
148
+ .split(/[\s_-]+/)
149
+ .filter(Boolean)
150
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
151
+ .join(' ');
152
+ }
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Phase 3: Selector Enforcement
3
+ * Validates selectors against whitelist and comments out invalid ones
4
+ */
5
+ export interface ValidationResult {
6
+ isValid: boolean;
7
+ confidence: number;
8
+ reason?: string;
9
+ suggestedComment?: string;
10
+ }
11
+ export interface ValidatedSelector {
12
+ selector: string;
13
+ isWhitelisted: boolean;
14
+ confidence: number;
15
+ originalCode: string;
16
+ validatedCode: string;
17
+ }
18
+ /**
19
+ * SelectorValidator: Enforces whitelist matching on generated selectors
20
+ * Comments out unobserved selectors instead of letting tests fail randomly
21
+ */
22
+ export declare class SelectorValidator {
23
+ private whitelist;
24
+ private semanticWhitelist;
25
+ private minConfidence;
26
+ constructor(globalSelectors: {
27
+ [semantic: string]: Array<{
28
+ selector: string;
29
+ confidence: number;
30
+ }>;
31
+ }, minConfidence?: number);
32
+ /**
33
+ * Validate a selector against the whitelist
34
+ */
35
+ validateSelector(selector: string): ValidationResult;
36
+ /**
37
+ * Validate and comment out invalid selectors in generated test code
38
+ */
39
+ validateTestCode(code: string): ValidatedSelector[];
40
+ /**
41
+ * Apply validation to test code, commenting out unwhitelisted selectors
42
+ */
43
+ applyValidation(code: string): string;
44
+ /**
45
+ * Get validation summary
46
+ */
47
+ getSummary(code: string): {
48
+ total: number;
49
+ whitelisted: number;
50
+ coverage: number;
51
+ unobserved: string[];
52
+ };
53
+ private normalizeSelector;
54
+ }
55
+ /**
56
+ * APIFallbackResolver: Provides fallback strategies when UI selectors fail
57
+ * Converts test methods to API calls when UI elements aren't available
58
+ */
59
+ export declare class APIFallbackResolver {
60
+ private apiMapping;
61
+ /**
62
+ * Check if a test should fall back to API testing
63
+ */
64
+ shouldFallback(selector: string, confidence: number): boolean;
65
+ /**
66
+ * Generate API-based fallback for unobserved selector
67
+ */
68
+ generateAPIFallback(selector: string, action: string): string;
69
+ /**
70
+ * Wrap unobserved test in try-catch with API fallback
71
+ */
72
+ wrapWithFallback(testCode: string): string;
73
+ }
74
+ //# sourceMappingURL=selector-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selector-validator.d.ts","sourceRoot":"","sources":["../../../src/agent/validators/selector-validator.ts"],"names":[],"mappings":"AAGA;;;GAGG;AAEH,MAAM,WAAW,gBAAgB;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,qBAAa,iBAAiB;IAC1B,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,iBAAiB,CAAoC;IAC7D,OAAO,CAAC,aAAa,CAAS;gBAG1B,eAAe,EAAE;QAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAA;SAAC,CAAC,CAAA;KAAC,EACpF,aAAa,GAAE,MAAW;IAkB9B;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB;IA6BpD;;OAEG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,EAAE;IAuBnD;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAcrC;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG;QACtB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,EAAE,CAAC;KACxB;IAeD,OAAO,CAAC,iBAAiB;CAI5B;AAED;;;GAGG;AACH,qBAAa,mBAAmB;IAC5B,OAAO,CAAC,UAAU,CAOf;IAEH;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO;IAI7D;;OAEG;IACH,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;IAmB7D;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;CAS7C"}
@@ -0,0 +1,165 @@
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.APIFallbackResolver = exports.SelectorValidator = void 0;
6
+ /**
7
+ * SelectorValidator: Enforces whitelist matching on generated selectors
8
+ * Comments out unobserved selectors instead of letting tests fail randomly
9
+ */
10
+ class SelectorValidator {
11
+ constructor(globalSelectors, minConfidence = 50) {
12
+ this.whitelist = new Set();
13
+ this.semanticWhitelist = new Map();
14
+ this.minConfidence = minConfidence;
15
+ // Build flat whitelist from semantic map
16
+ for (const [semantic, elements] of Object.entries(globalSelectors)) {
17
+ for (const elem of elements) {
18
+ if (elem.confidence >= minConfidence) {
19
+ this.whitelist.add(elem.selector);
20
+ }
21
+ }
22
+ this.semanticWhitelist.set(semantic, elements.map((e) => e.selector));
23
+ }
24
+ }
25
+ /**
26
+ * Validate a selector against the whitelist
27
+ */
28
+ validateSelector(selector) {
29
+ if (this.whitelist.has(selector)) {
30
+ return {
31
+ isValid: true,
32
+ confidence: 100,
33
+ reason: 'Found in whitelist',
34
+ };
35
+ }
36
+ // Check for similar selectors (lenient matching)
37
+ const normalized = this.normalizeSelector(selector);
38
+ for (const whitelisted of this.whitelist) {
39
+ if (this.normalizeSelector(whitelisted).includes(normalized)) {
40
+ return {
41
+ isValid: true,
42
+ confidence: 75,
43
+ reason: 'Found similar whitelisted selector',
44
+ };
45
+ }
46
+ }
47
+ return {
48
+ isValid: false,
49
+ confidence: 0,
50
+ reason: 'Not found in whitelist',
51
+ suggestedComment: `// UNOBSERVED SELECTOR - Not found in UI map. Use test.fixme() if needed.`,
52
+ };
53
+ }
54
+ /**
55
+ * Validate and comment out invalid selectors in generated test code
56
+ */
57
+ validateTestCode(code) {
58
+ const results = [];
59
+ const selectorRegex = /page\.(getByTestId|getByLabel|getByRole|locator)\(['"`]([^'"`]+)['"`]\)/g;
60
+ let match;
61
+ while ((match = selectorRegex.exec(code)) !== null) {
62
+ const [fullMatch, , selector] = match;
63
+ const validation = this.validateSelector(selector);
64
+ results.push({
65
+ selector,
66
+ isWhitelisted: validation.isValid,
67
+ confidence: validation.confidence,
68
+ originalCode: fullMatch,
69
+ validatedCode: validation.isValid
70
+ ? fullMatch
71
+ : `// ${validation.suggestedComment}\n // ${fullMatch}`,
72
+ });
73
+ }
74
+ return results;
75
+ }
76
+ /**
77
+ * Apply validation to test code, commenting out unwhitelisted selectors
78
+ */
79
+ applyValidation(code) {
80
+ let validated = code;
81
+ const results = this.validateTestCode(code);
82
+ // Apply in reverse order to preserve indices
83
+ for (const result of results.reverse()) {
84
+ if (!result.isWhitelisted) {
85
+ validated = validated.replace(result.originalCode, result.validatedCode);
86
+ }
87
+ }
88
+ return validated;
89
+ }
90
+ /**
91
+ * Get validation summary
92
+ */
93
+ getSummary(code) {
94
+ const results = this.validateTestCode(code);
95
+ const unobserved = results.filter((r) => !r.isWhitelisted).map((r) => r.selector);
96
+ return {
97
+ total: results.length,
98
+ whitelisted: results.filter((r) => r.isWhitelisted).length,
99
+ coverage: results.length > 0
100
+ ? Math.round((results.filter((r) => r.isWhitelisted).length / results.length) * 100)
101
+ : 100,
102
+ unobserved,
103
+ };
104
+ }
105
+ normalizeSelector(selector) {
106
+ // Normalize selector for lenient matching
107
+ return selector.toLowerCase().replace(/[^a-z0-9-_]/g, '');
108
+ }
109
+ }
110
+ exports.SelectorValidator = SelectorValidator;
111
+ /**
112
+ * APIFallbackResolver: Provides fallback strategies when UI selectors fail
113
+ * Converts test methods to API calls when UI elements aren't available
114
+ */
115
+ class APIFallbackResolver {
116
+ constructor() {
117
+ this.apiMapping = new Map([
118
+ // UI action -> API endpoint mapping
119
+ ['click.*button.*submit', 'POST /api/v4/posts'],
120
+ ['fill.*search', 'GET /api/v4/users'],
121
+ ['click.*profile', 'GET /api/v4/users/me'],
122
+ ['navigate.*channel', 'GET /api/v4/channels'],
123
+ ['click.*settings', 'PATCH /api/v4/users/me'],
124
+ ]);
125
+ }
126
+ /**
127
+ * Check if a test should fall back to API testing
128
+ */
129
+ shouldFallback(selector, confidence) {
130
+ return confidence < 50;
131
+ }
132
+ /**
133
+ * Generate API-based fallback for unobserved selector
134
+ */
135
+ generateAPIFallback(selector, action) {
136
+ // Find matching API endpoint
137
+ let endpoint = 'GET /api/v4/';
138
+ for (const [pattern, api] of this.apiMapping) {
139
+ if (new RegExp(pattern, 'i').test(action)) {
140
+ endpoint = api;
141
+ break;
142
+ }
143
+ }
144
+ return `
145
+ // UI selector not found - falling back to API
146
+ const response = await fetch(\`\${baseUrl}${endpoint.split(' ')[1]}\`, {
147
+ method: '${endpoint.split(' ')[0]}',
148
+ headers: {'Authorization': \`Bearer \${token}\`},
149
+ });
150
+ expect(response.ok).toBe(true);`;
151
+ }
152
+ /**
153
+ * Wrap unobserved test in try-catch with API fallback
154
+ */
155
+ wrapWithFallback(testCode) {
156
+ return `
157
+ try {
158
+ ${testCode}
159
+ } catch (error) {
160
+ // UI element not found - using API fallback
161
+ ${this.generateAPIFallback('unknown', testCode)}
162
+ }`;
163
+ }
164
+ }
165
+ exports.APIFallbackResolver = APIFallbackResolver;
@@ -0,0 +1,65 @@
1
+ import type { AnthropicConfig, GenerateOptions, ImageInput, LLMResponse, ProviderCapabilities } from './provider_interface.js';
2
+ import { BaseProvider } from './base_provider.js';
3
+ /**
4
+ * Anthropic Provider - Claude AI models
5
+ *
6
+ * Features:
7
+ * - Highest quality AI (98% accuracy in testing)
8
+ * - Vision support (analyze screenshots, compare UI)
9
+ * - Fast response times (<1 second)
10
+ * - 200K token context window
11
+ * - Prompt caching (reduces costs by 90% on repeated prompts)
12
+ *
13
+ * Costs (Claude Sonnet 4.5):
14
+ * - Input: $3 per 1M tokens
15
+ * - Output: $15 per 1M tokens
16
+ * - Cached input: $0.30 per 1M tokens
17
+ * - Estimated: ~$30-80/month for autonomous testing
18
+ *
19
+ * Use cases:
20
+ * - Vision tasks (screenshot comparison)
21
+ * - Complex failure diagnosis
22
+ * - High-stakes production testing
23
+ * - When quality is paramount
24
+ *
25
+ * Models:
26
+ * - claude-sonnet-4-5-20250929 (recommended - best balance)
27
+ * - claude-opus-4-5-20251101 (highest quality, slower, more expensive)
28
+ * - claude-haiku-4-0-20250430 (fastest, cheapest, lower quality)
29
+ */
30
+ export declare class AnthropicProvider extends BaseProvider {
31
+ name: string;
32
+ private client;
33
+ private model;
34
+ capabilities: ProviderCapabilities;
35
+ constructor(config: AnthropicConfig);
36
+ generateText(prompt: string, options?: GenerateOptions): Promise<LLMResponse>;
37
+ analyzeImage(images: ImageInput[], prompt: string, options?: GenerateOptions): Promise<LLMResponse>;
38
+ streamText(prompt: string, options?: GenerateOptions): AsyncGenerator<string, void, unknown>;
39
+ private extractTextFromResponse;
40
+ /**
41
+ * SECURITY: Type-safe usage extraction
42
+ * Avoids unsafe `as any` casts
43
+ */
44
+ private extractUsageFromResponse;
45
+ /**
46
+ * SECURITY: Extract status code safely
47
+ */
48
+ private extractStatusCode;
49
+ /**
50
+ * Check if API key is valid and service is accessible
51
+ */
52
+ checkHealth(): Promise<{
53
+ healthy: boolean;
54
+ message: string;
55
+ }>;
56
+ }
57
+ /**
58
+ * Helper to check Anthropic setup
59
+ */
60
+ export declare function checkAnthropicSetup(apiKey: string): Promise<{
61
+ valid: boolean;
62
+ message: string;
63
+ estimatedMonthlyCost: string;
64
+ }>;
65
+ //# sourceMappingURL=anthropic_provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic_provider.d.ts","sourceRoot":"","sources":["../src/anthropic_provider.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACR,eAAe,EACf,eAAe,EACf,UAAU,EACV,WAAW,EACX,oBAAoB,EACvB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAehD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,iBAAkB,SAAQ,YAAY;IAC/C,IAAI,SAAe;IACnB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,KAAK,CAAS;IAEtB,YAAY,EAAE,oBAAoB,CAShC;gBAEU,MAAM,EAAE,eAAe;IA2B7B,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC;IA4D7E,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC;IAgHlG,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC;IA4CnG,OAAO,CAAC,uBAAuB;IAU/B;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAchC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAWzB;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAC,CAAC;CAyBpE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/D,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB,EAAE,MAAM,CAAC;CAChC,CAAC,CAyBD"}