@tayo-dev/rtl 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +250 -0
- package/dist/analyzer/mocks/detector.d.ts +59 -0
- package/dist/analyzer/mocks/detector.d.ts.map +1 -0
- package/dist/analyzer/mocks/detector.js +264 -0
- package/dist/analyzer/mocks/detector.js.map +1 -0
- package/dist/analyzer/mocks/target-analyzer.d.ts +92 -0
- package/dist/analyzer/mocks/target-analyzer.d.ts.map +1 -0
- package/dist/analyzer/mocks/target-analyzer.js +305 -0
- package/dist/analyzer/mocks/target-analyzer.js.map +1 -0
- package/dist/analyzer/visual/element-analyzer.d.ts +44 -0
- package/dist/analyzer/visual/element-analyzer.d.ts.map +1 -0
- package/dist/analyzer/visual/element-analyzer.js +176 -0
- package/dist/analyzer/visual/element-analyzer.js.map +1 -0
- package/dist/analyzer/visual/inspector.d.ts +49 -0
- package/dist/analyzer/visual/inspector.d.ts.map +1 -0
- package/dist/analyzer/visual/inspector.js +109 -0
- package/dist/analyzer/visual/inspector.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +13 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +417 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/core/generator.d.ts +32 -0
- package/dist/core/generator.d.ts.map +1 -0
- package/dist/core/generator.js +173 -0
- package/dist/core/generator.js.map +1 -0
- package/dist/core/js-parser.d.ts +48 -0
- package/dist/core/js-parser.d.ts.map +1 -0
- package/dist/core/js-parser.js +244 -0
- package/dist/core/js-parser.js.map +1 -0
- package/dist/core/mock-intelligence.d.ts +14 -0
- package/dist/core/mock-intelligence.d.ts.map +1 -0
- package/dist/core/mock-intelligence.js +140 -0
- package/dist/core/mock-intelligence.js.map +1 -0
- package/dist/core/orchestrator.d.ts +49 -0
- package/dist/core/orchestrator.d.ts.map +1 -0
- package/dist/core/orchestrator.js +315 -0
- package/dist/core/orchestrator.js.map +1 -0
- package/dist/core/parser.d.ts +9 -0
- package/dist/core/parser.d.ts.map +1 -0
- package/dist/core/parser.js +120 -0
- package/dist/core/parser.js.map +1 -0
- package/dist/core/recording-intelligence.d.ts +15 -0
- package/dist/core/recording-intelligence.d.ts.map +1 -0
- package/dist/core/recording-intelligence.js +178 -0
- package/dist/core/recording-intelligence.js.map +1 -0
- package/dist/core/resolver.d.ts +58 -0
- package/dist/core/resolver.d.ts.map +1 -0
- package/dist/core/resolver.js +291 -0
- package/dist/core/resolver.js.map +1 -0
- package/dist/core/scanner.d.ts +51 -0
- package/dist/core/scanner.d.ts.map +1 -0
- package/dist/core/scanner.js +310 -0
- package/dist/core/scanner.js.map +1 -0
- package/dist/core/scorer.d.ts +8 -0
- package/dist/core/scorer.d.ts.map +1 -0
- package/dist/core/scorer.js +76 -0
- package/dist/core/scorer.js.map +1 -0
- package/dist/core/validator.d.ts +134 -0
- package/dist/core/validator.d.ts.map +1 -0
- package/dist/core/validator.js +44 -0
- package/dist/core/validator.js.map +1 -0
- package/dist/core/verifier.d.ts +10 -0
- package/dist/core/verifier.d.ts.map +1 -0
- package/dist/core/verifier.js +30 -0
- package/dist/core/verifier.js.map +1 -0
- package/dist/core/writer.d.ts +15 -0
- package/dist/core/writer.d.ts.map +1 -0
- package/dist/core/writer.js +43 -0
- package/dist/core/writer.js.map +1 -0
- package/dist/generator/mocks/builder.d.ts +47 -0
- package/dist/generator/mocks/builder.d.ts.map +1 -0
- package/dist/generator/mocks/builder.js +335 -0
- package/dist/generator/mocks/builder.js.map +1 -0
- package/dist/generator/transforms/dialog-transform.d.ts +35 -0
- package/dist/generator/transforms/dialog-transform.d.ts.map +1 -0
- package/dist/generator/transforms/dialog-transform.js +293 -0
- package/dist/generator/transforms/dialog-transform.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/learner/analyzer.d.ts +13 -0
- package/dist/learner/analyzer.d.ts.map +1 -0
- package/dist/learner/analyzer.js +484 -0
- package/dist/learner/analyzer.js.map +1 -0
- package/dist/learner/index.d.ts +66 -0
- package/dist/learner/index.d.ts.map +1 -0
- package/dist/learner/index.js +247 -0
- package/dist/learner/index.js.map +1 -0
- package/dist/learner/storage.d.ts +68 -0
- package/dist/learner/storage.d.ts.map +1 -0
- package/dist/learner/storage.js +201 -0
- package/dist/learner/storage.js.map +1 -0
- package/dist/learner/types.d.ts +41 -0
- package/dist/learner/types.d.ts.map +1 -0
- package/dist/learner/types.js +31 -0
- package/dist/learner/types.js.map +1 -0
- package/dist/parser/recorder-parser.d.ts +40 -0
- package/dist/parser/recorder-parser.d.ts.map +1 -0
- package/dist/parser/recorder-parser.js +139 -0
- package/dist/parser/recorder-parser.js.map +1 -0
- package/dist/parser/steps/deduplicator.d.ts +19 -0
- package/dist/parser/steps/deduplicator.d.ts.map +1 -0
- package/dist/parser/steps/deduplicator.js +75 -0
- package/dist/parser/steps/deduplicator.js.map +1 -0
- package/dist/parser/steps/dialog-detector.d.ts +38 -0
- package/dist/parser/steps/dialog-detector.d.ts.map +1 -0
- package/dist/parser/steps/dialog-detector.js +290 -0
- package/dist/parser/steps/dialog-detector.js.map +1 -0
- package/dist/parser/steps/noise-filter.d.ts +21 -0
- package/dist/parser/steps/noise-filter.d.ts.map +1 -0
- package/dist/parser/steps/noise-filter.js +138 -0
- package/dist/parser/steps/noise-filter.js.map +1 -0
- package/dist/scorer/index.d.ts +43 -0
- package/dist/scorer/index.d.ts.map +1 -0
- package/dist/scorer/index.js +82 -0
- package/dist/scorer/index.js.map +1 -0
- package/dist/scorer/post-verify.d.ts +17 -0
- package/dist/scorer/post-verify.d.ts.map +1 -0
- package/dist/scorer/post-verify.js +163 -0
- package/dist/scorer/post-verify.js.map +1 -0
- package/dist/scorer/pre-audit.d.ts +32 -0
- package/dist/scorer/pre-audit.d.ts.map +1 -0
- package/dist/scorer/pre-audit.js +99 -0
- package/dist/scorer/pre-audit.js.map +1 -0
- package/dist/scorer/quality-gates.d.ts +17 -0
- package/dist/scorer/quality-gates.d.ts.map +1 -0
- package/dist/scorer/quality-gates.js +304 -0
- package/dist/scorer/quality-gates.js.map +1 -0
- package/dist/scorer/types.d.ts +27 -0
- package/dist/scorer/types.d.ts.map +1 -0
- package/dist/scorer/types.js +5 -0
- package/dist/scorer/types.js.map +1 -0
- package/dist/templates/test-template.d.ts +21 -0
- package/dist/templates/test-template.d.ts.map +1 -0
- package/dist/templates/test-template.js +92 -0
- package/dist/templates/test-template.js.map +1 -0
- package/dist/types/conventions.d.ts +49 -0
- package/dist/types/conventions.d.ts.map +1 -0
- package/dist/types/conventions.js +13 -0
- package/dist/types/conventions.js.map +1 -0
- package/dist/types/recording.d.ts +143 -0
- package/dist/types/recording.d.ts.map +1 -0
- package/dist/types/recording.js +5 -0
- package/dist/types/recording.js.map +1 -0
- package/dist/types/score.d.ts +18 -0
- package/dist/types/score.d.ts.map +1 -0
- package/dist/types/score.js +2 -0
- package/dist/types/score.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quality gates evaluation using AST-based analysis
|
|
3
|
+
*/
|
|
4
|
+
import { parse } from '@typescript-eslint/typescript-estree';
|
|
5
|
+
/**
|
|
6
|
+
* Evaluate quality gates on test code
|
|
7
|
+
*/
|
|
8
|
+
export function evaluateQualityGates(code) {
|
|
9
|
+
const issues = [];
|
|
10
|
+
let ast;
|
|
11
|
+
try {
|
|
12
|
+
ast = parse(code, {
|
|
13
|
+
loc: true,
|
|
14
|
+
range: true,
|
|
15
|
+
jsx: true,
|
|
16
|
+
ecmaVersion: 2020,
|
|
17
|
+
sourceType: 'module'
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
issues.push({
|
|
22
|
+
type: 'structure',
|
|
23
|
+
severity: 'error',
|
|
24
|
+
message: 'Failed to parse code - syntax error',
|
|
25
|
+
suggestion: 'Check for valid TypeScript/JavaScript syntax'
|
|
26
|
+
});
|
|
27
|
+
return {
|
|
28
|
+
overall: 0,
|
|
29
|
+
criteria: { structure: 0, queries: 0, matchers: 0, noFragility: 0 },
|
|
30
|
+
issues,
|
|
31
|
+
passed: false
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
// Evaluate each criterion
|
|
35
|
+
const structure = evaluateStructure(ast, issues);
|
|
36
|
+
const queries = evaluateQueries(code, ast, issues);
|
|
37
|
+
const matchers = evaluateMatchers(ast, issues);
|
|
38
|
+
const noFragility = evaluateNoFragility(code, ast, issues);
|
|
39
|
+
// Calculate weighted overall score
|
|
40
|
+
const overall = Math.round(structure * 0.25 +
|
|
41
|
+
queries * 0.25 +
|
|
42
|
+
matchers * 0.30 +
|
|
43
|
+
noFragility * 0.20);
|
|
44
|
+
return {
|
|
45
|
+
overall,
|
|
46
|
+
criteria: { structure, queries, matchers, noFragility },
|
|
47
|
+
issues,
|
|
48
|
+
passed: overall >= 50 // Minimum threshold to pass
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Evaluate test structure (describe/it blocks)
|
|
53
|
+
*/
|
|
54
|
+
function evaluateStructure(ast, issues) {
|
|
55
|
+
let hasDescribe = false;
|
|
56
|
+
let hasTest = false;
|
|
57
|
+
function traverse(node) {
|
|
58
|
+
if (!node)
|
|
59
|
+
return;
|
|
60
|
+
if (node.type === 'CallExpression' && node.callee) {
|
|
61
|
+
const calleeName = getCalleeName(node.callee);
|
|
62
|
+
if (calleeName === 'describe')
|
|
63
|
+
hasDescribe = true;
|
|
64
|
+
if (calleeName === 'it' || calleeName === 'test')
|
|
65
|
+
hasTest = true;
|
|
66
|
+
}
|
|
67
|
+
// Recursively traverse children
|
|
68
|
+
if (Array.isArray(node.body)) {
|
|
69
|
+
node.body.forEach(traverse);
|
|
70
|
+
}
|
|
71
|
+
else if (node.body && typeof node.body === 'object') {
|
|
72
|
+
traverse(node.body);
|
|
73
|
+
}
|
|
74
|
+
// Also traverse function expression and arrow function bodies
|
|
75
|
+
if (node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression') {
|
|
76
|
+
if (node.body) {
|
|
77
|
+
if (Array.isArray(node.body)) {
|
|
78
|
+
node.body.forEach(traverse);
|
|
79
|
+
}
|
|
80
|
+
else if (typeof node.body === 'object') {
|
|
81
|
+
traverse(node.body);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (node.arguments) {
|
|
86
|
+
node.arguments.forEach(arg => traverse(arg));
|
|
87
|
+
}
|
|
88
|
+
// Traverse expression for chaining like expect(x).toBe()
|
|
89
|
+
if (node.expression) {
|
|
90
|
+
traverse(node.expression);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
traverse(ast);
|
|
94
|
+
if (!hasDescribe) {
|
|
95
|
+
issues.push({
|
|
96
|
+
type: 'structure',
|
|
97
|
+
severity: 'error',
|
|
98
|
+
message: 'Missing describe block',
|
|
99
|
+
suggestion: 'Wrap tests in describe() to organize test cases'
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
if (!hasTest) {
|
|
103
|
+
issues.push({
|
|
104
|
+
type: 'structure',
|
|
105
|
+
severity: 'error',
|
|
106
|
+
message: 'Missing test case (it/test)',
|
|
107
|
+
suggestion: 'Add it() or test() blocks for test cases'
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
// Score: 50 for having describe, +50 for having test block
|
|
111
|
+
return (hasDescribe ? 50 : 0) + (hasTest ? 50 : 0);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Evaluate query robustness
|
|
115
|
+
*/
|
|
116
|
+
function evaluateQueries(code, ast, issues) {
|
|
117
|
+
const robustQueries = ['getByRole', 'getByLabelText', 'getByText', 'findByRole', 'findByLabelText', 'queryByRole', 'getByPlaceholderText'];
|
|
118
|
+
const fragileQueries = ['querySelector', 'getByTestId', 'queryByTestId'];
|
|
119
|
+
let robustCount = 0;
|
|
120
|
+
let fragileCount = 0;
|
|
121
|
+
// Check for query methods in code
|
|
122
|
+
robustQueries.forEach(q => {
|
|
123
|
+
if (code.includes(q))
|
|
124
|
+
robustCount++;
|
|
125
|
+
});
|
|
126
|
+
fragileQueries.forEach(q => {
|
|
127
|
+
if (code.includes(q))
|
|
128
|
+
fragileCount++;
|
|
129
|
+
});
|
|
130
|
+
if (fragileCount > 0 && robustCount === 0) {
|
|
131
|
+
issues.push({
|
|
132
|
+
type: 'queries',
|
|
133
|
+
severity: 'warning',
|
|
134
|
+
message: 'Using fragile queries (getByTestId, querySelector)',
|
|
135
|
+
suggestion: 'Prefer getByRole, getByLabelText, getByText for accessibility'
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
if (robustCount > 0) {
|
|
139
|
+
return Math.min(100, 50 + (robustCount * 10));
|
|
140
|
+
}
|
|
141
|
+
return fragileCount > 0 ? 30 : 50;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Evaluate assertion matchers
|
|
145
|
+
*/
|
|
146
|
+
function evaluateMatchers(ast, issues) {
|
|
147
|
+
let expectCount = 0;
|
|
148
|
+
let matcherCount = 0;
|
|
149
|
+
function traverse(node) {
|
|
150
|
+
if (!node)
|
|
151
|
+
return;
|
|
152
|
+
// Check for expect() calls - look for CallExpression where callee starts with 'expect'
|
|
153
|
+
if (node.type === 'CallExpression' && node.callee) {
|
|
154
|
+
const calleeSource = getCalleeSource(node.callee);
|
|
155
|
+
if (calleeSource && calleeSource.startsWith('expect')) {
|
|
156
|
+
expectCount++;
|
|
157
|
+
// Check if has arguments
|
|
158
|
+
if (node.arguments && node.arguments.length > 0) {
|
|
159
|
+
matcherCount++;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
// Check for common matchers in chained calls like expect(x).toBe(y)
|
|
164
|
+
const matcherNames = ['toBe', 'toEqual', 'toContain', 'toHaveLength', 'toBeTruthy', 'toBeFalsy', 'toBeInTheDocument', 'toBeVisible', 'toHaveTextContent'];
|
|
165
|
+
if (node.type === 'MemberExpression' && node.property) {
|
|
166
|
+
const prop = node.property;
|
|
167
|
+
const propName = typeof prop.name === 'string' ? prop.name : '';
|
|
168
|
+
if (matcherNames.includes(propName)) {
|
|
169
|
+
matcherCount++;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// Recursively traverse all node types
|
|
173
|
+
if (Array.isArray(node.body)) {
|
|
174
|
+
node.body.forEach(traverse);
|
|
175
|
+
}
|
|
176
|
+
else if (node.body && typeof node.body === 'object') {
|
|
177
|
+
traverse(node.body);
|
|
178
|
+
}
|
|
179
|
+
// Handle function expressions and arrow functions
|
|
180
|
+
if (node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression') {
|
|
181
|
+
if (node.body) {
|
|
182
|
+
if (Array.isArray(node.body)) {
|
|
183
|
+
node.body.forEach(traverse);
|
|
184
|
+
}
|
|
185
|
+
else if (typeof node.body === 'object') {
|
|
186
|
+
traverse(node.body);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (node.arguments) {
|
|
191
|
+
node.arguments.forEach(arg => traverse(arg));
|
|
192
|
+
}
|
|
193
|
+
if (node.expression) {
|
|
194
|
+
traverse(node.expression);
|
|
195
|
+
}
|
|
196
|
+
// Handle object properties
|
|
197
|
+
if (node.properties) {
|
|
198
|
+
node.properties.forEach((prop) => traverse(prop));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
traverse(ast);
|
|
202
|
+
if (expectCount === 0) {
|
|
203
|
+
issues.push({
|
|
204
|
+
type: 'matchers',
|
|
205
|
+
severity: 'error',
|
|
206
|
+
message: 'No expect statements found',
|
|
207
|
+
suggestion: 'Add assertions using expect() with matchers like toBe(), toEqual()'
|
|
208
|
+
});
|
|
209
|
+
return 0;
|
|
210
|
+
}
|
|
211
|
+
if (matcherCount < expectCount) {
|
|
212
|
+
return Math.min(100, 50 + (matcherCount * 15));
|
|
213
|
+
}
|
|
214
|
+
return Math.min(100, 50 + (expectCount * 10));
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Evaluate fragility - avoid CSS selectors and test IDs as primary queries
|
|
218
|
+
*/
|
|
219
|
+
function evaluateNoFragility(code, ast, issues) {
|
|
220
|
+
// Check for CSS selectors - but avoid false positives from method calls
|
|
221
|
+
// More careful patterns that exclude method chains like getByRole, queryByText
|
|
222
|
+
const cssSelectors = [
|
|
223
|
+
/(?:^|[^.\w])#[a-zA-Z][\w-]*/, // ID selectors (#button) - not preceded by word char
|
|
224
|
+
/\[[\w-]+=["'][^"']*["']\]/, // attribute selectors [data-testid="x"]
|
|
225
|
+
/document\.querySelector/,
|
|
226
|
+
/document\.getElementBy/
|
|
227
|
+
];
|
|
228
|
+
// Also check for standalone class selectors that are not part of method chains
|
|
229
|
+
const classSelectorRegex = /(?<![a-zA-Z])\.[a-zA-Z][\w-]*(?![a-zA-Z(])/g;
|
|
230
|
+
let cssSelectorCount = 0;
|
|
231
|
+
cssSelectors.forEach(regex => {
|
|
232
|
+
const matches = code.match(regex);
|
|
233
|
+
if (matches)
|
|
234
|
+
cssSelectorCount += matches.length;
|
|
235
|
+
});
|
|
236
|
+
// Check for class selectors separately
|
|
237
|
+
const classMatches = code.match(classSelectorRegex);
|
|
238
|
+
if (classMatches)
|
|
239
|
+
cssSelectorCount += classMatches.length;
|
|
240
|
+
// Check for test IDs (data-testid)
|
|
241
|
+
const testIdRegex = /data-testid=["']([^"']+)["']/g;
|
|
242
|
+
const testIdMatches = code.match(testIdRegex);
|
|
243
|
+
const testIdCount = testIdMatches ? testIdMatches.length : 0;
|
|
244
|
+
if (cssSelectorCount > 0) {
|
|
245
|
+
issues.push({
|
|
246
|
+
type: 'fragility',
|
|
247
|
+
severity: 'warning',
|
|
248
|
+
message: `Found ${cssSelectorCount} CSS selector(s) - fragile to style changes`,
|
|
249
|
+
suggestion: 'Use semantic queries like getByRole for better resilience'
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
if (testIdCount > 0) {
|
|
253
|
+
issues.push({
|
|
254
|
+
type: 'fragility',
|
|
255
|
+
severity: 'info',
|
|
256
|
+
message: `Found ${testIdCount} test ID(s) - acceptable but not ideal`,
|
|
257
|
+
suggestion: 'Prefer semantic queries when possible'
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
// Score based on absence of fragile patterns
|
|
261
|
+
if (cssSelectorCount === 0 && testIdCount === 0)
|
|
262
|
+
return 100;
|
|
263
|
+
if (cssSelectorCount === 0)
|
|
264
|
+
return 80;
|
|
265
|
+
if (testIdCount === 0)
|
|
266
|
+
return 70;
|
|
267
|
+
return 50;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Get the full source of a callee including chained calls (e.g., "expect", "expect().toBe")
|
|
271
|
+
*/
|
|
272
|
+
function getCalleeSource(callee) {
|
|
273
|
+
if (callee.type === 'Identifier') {
|
|
274
|
+
return callee.name || '';
|
|
275
|
+
}
|
|
276
|
+
if (callee.type === 'MemberExpression' && callee.object) {
|
|
277
|
+
// For chained calls like expect().toBe(), get the object part first
|
|
278
|
+
const objectSource = getCalleeSource(callee.object);
|
|
279
|
+
const prop = callee.property;
|
|
280
|
+
const propName = typeof prop.name === 'string' ? prop.name : '';
|
|
281
|
+
return objectSource ? `${objectSource}.${propName}` : propName;
|
|
282
|
+
}
|
|
283
|
+
if (callee.type === 'CallExpression' && callee.callee) {
|
|
284
|
+
return getCalleeSource(callee.callee);
|
|
285
|
+
}
|
|
286
|
+
return '';
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Get the name of a callee (handles nested calls like expect().toBe)
|
|
290
|
+
*/
|
|
291
|
+
function getCalleeName(callee) {
|
|
292
|
+
if (callee.type === 'Identifier') {
|
|
293
|
+
return callee.name || '';
|
|
294
|
+
}
|
|
295
|
+
if (callee.type === 'MemberExpression' && callee.property) {
|
|
296
|
+
const prop = callee.property;
|
|
297
|
+
return typeof prop.name === 'string' ? prop.name : '';
|
|
298
|
+
}
|
|
299
|
+
if (callee.type === 'CallExpression' && callee.callee) {
|
|
300
|
+
return getCalleeName(callee.callee);
|
|
301
|
+
}
|
|
302
|
+
return '';
|
|
303
|
+
}
|
|
304
|
+
//# sourceMappingURL=quality-gates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quality-gates.js","sourceRoot":"","sources":["../../src/scorer/quality-gates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quality scoring types for test evaluation
|
|
3
|
+
*/
|
|
4
|
+
export interface QualityCriteria {
|
|
5
|
+
structure: number;
|
|
6
|
+
queries: number;
|
|
7
|
+
matchers: number;
|
|
8
|
+
noFragility: number;
|
|
9
|
+
}
|
|
10
|
+
export interface QualityIssue {
|
|
11
|
+
type: 'structure' | 'queries' | 'matchers' | 'fragility';
|
|
12
|
+
severity: 'error' | 'warning' | 'info';
|
|
13
|
+
message: string;
|
|
14
|
+
suggestion?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface QualityScore {
|
|
17
|
+
overall: number;
|
|
18
|
+
criteria: QualityCriteria;
|
|
19
|
+
issues: QualityIssue[];
|
|
20
|
+
passed: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface ScoringResult {
|
|
23
|
+
score: QualityScore;
|
|
24
|
+
code: string;
|
|
25
|
+
timestamp: number;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/scorer/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;IACzD,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,eAAe,CAAC;IAC1B,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,YAAY,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/scorer/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code templates for RTL test structure.
|
|
3
|
+
* Functions return string fragments for composing test files.
|
|
4
|
+
*/
|
|
5
|
+
import type { NormalizedAction } from '../types/recording.js';
|
|
6
|
+
export declare function importBlock(hasUserEvents: boolean, importStyle?: 'esm' | 'cjs'): string;
|
|
7
|
+
export interface StepTemplateOptions {
|
|
8
|
+
action: NormalizedAction;
|
|
9
|
+
query: string;
|
|
10
|
+
value?: string;
|
|
11
|
+
matcher?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function stepTemplate(opts: StepTemplateOptions): string;
|
|
14
|
+
export declare function describeBlock(name: string, bodyLines: string[], hasUserEvents: boolean): string;
|
|
15
|
+
export interface ItBlockTemplate {
|
|
16
|
+
name: string;
|
|
17
|
+
stepLines: string[];
|
|
18
|
+
hasUserEvents: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare function describeBlockMultiIt(name: string, itBlocks: ItBlockTemplate[]): string;
|
|
21
|
+
//# sourceMappingURL=test-template.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-template.d.ts","sourceRoot":"","sources":["../../src/templates/test-template.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAE7D,wBAAgB,WAAW,CAAC,aAAa,EAAE,OAAO,EAAE,WAAW,GAAE,KAAK,GAAG,KAAa,GAAG,MAAM,CAoB9F;AAcD,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,gBAAgB,CAAA;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAiC9D;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EAAE,EACnB,aAAa,EAAE,OAAO,GACrB,MAAM,CAYR;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,aAAa,EAAE,OAAO,CAAA;CACvB;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,eAAe,EAAE,GAC1B,MAAM,CAiBR"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code templates for RTL test structure.
|
|
3
|
+
* Functions return string fragments for composing test files.
|
|
4
|
+
*/
|
|
5
|
+
export function importBlock(hasUserEvents, importStyle = 'esm') {
|
|
6
|
+
if (importStyle === 'cjs') {
|
|
7
|
+
const lines = [
|
|
8
|
+
"const { render, screen } = require('@testing-library/react')",
|
|
9
|
+
"require('@testing-library/jest-dom')",
|
|
10
|
+
];
|
|
11
|
+
if (hasUserEvents) {
|
|
12
|
+
lines.push("const userEvent = require('@testing-library/user-event')");
|
|
13
|
+
}
|
|
14
|
+
return lines.join('\n');
|
|
15
|
+
}
|
|
16
|
+
// ESM (default)
|
|
17
|
+
const lines = [
|
|
18
|
+
"import { render, screen } from '@testing-library/react'",
|
|
19
|
+
"import '@testing-library/jest-dom'",
|
|
20
|
+
];
|
|
21
|
+
if (hasUserEvents) {
|
|
22
|
+
lines.push("import userEvent from '@testing-library/user-event'");
|
|
23
|
+
}
|
|
24
|
+
return lines.join('\n');
|
|
25
|
+
}
|
|
26
|
+
function escapeSingleQuote(s) {
|
|
27
|
+
return s.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
|
28
|
+
}
|
|
29
|
+
function indentLines(text, spaces) {
|
|
30
|
+
const pad = ' '.repeat(spaces);
|
|
31
|
+
return text
|
|
32
|
+
.split('\n')
|
|
33
|
+
.map((line) => (line.trim() ? pad + line : ''))
|
|
34
|
+
.join('\n');
|
|
35
|
+
}
|
|
36
|
+
export function stepTemplate(opts) {
|
|
37
|
+
const { action, query, value = '' } = opts;
|
|
38
|
+
const escapedValue = escapeSingleQuote(value);
|
|
39
|
+
switch (action) {
|
|
40
|
+
case 'click':
|
|
41
|
+
return `await user.click(${query})`;
|
|
42
|
+
case 'fill':
|
|
43
|
+
return [
|
|
44
|
+
`await user.clear(${query})`,
|
|
45
|
+
`await user.type(${query}, '${escapedValue}')`,
|
|
46
|
+
].join('\n');
|
|
47
|
+
case 'select':
|
|
48
|
+
return `await user.selectOptions(${query}, '${escapedValue}')`;
|
|
49
|
+
case 'scroll':
|
|
50
|
+
return `${query}.scrollIntoView()`;
|
|
51
|
+
case 'assert':
|
|
52
|
+
return `expect(${query})${opts.matcher ?? '.toBeInTheDocument()'}`;
|
|
53
|
+
case 'navigate':
|
|
54
|
+
return `// navigate: ${value || query}`;
|
|
55
|
+
case 'keyDown':
|
|
56
|
+
return `await user.keyboard('${escapedValue}')`;
|
|
57
|
+
case 'unknown':
|
|
58
|
+
default:
|
|
59
|
+
return `// TODO: unsupported step — original selector: ${query}`;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export function describeBlock(name, bodyLines, hasUserEvents) {
|
|
63
|
+
const body = bodyLines.join('\n');
|
|
64
|
+
const indented = indentLines(body, 4);
|
|
65
|
+
const setupLine = hasUserEvents ? ` const user = userEvent.setup()\n` : '';
|
|
66
|
+
return [
|
|
67
|
+
`describe('${escapeSingleQuote(name)}', () => {`,
|
|
68
|
+
` it('should complete the recorded flow', async () => {`,
|
|
69
|
+
`${setupLine}`,
|
|
70
|
+
indented,
|
|
71
|
+
` })`,
|
|
72
|
+
`})`,
|
|
73
|
+
].join('\n');
|
|
74
|
+
}
|
|
75
|
+
export function describeBlockMultiIt(name, itBlocks) {
|
|
76
|
+
const escapedName = escapeSingleQuote(name);
|
|
77
|
+
const blocks = itBlocks.map((block) => {
|
|
78
|
+
const setup = block.hasUserEvents
|
|
79
|
+
? ` const user = userEvent.setup()\n`
|
|
80
|
+
: '';
|
|
81
|
+
const indented = indentLines(block.stepLines.join('\n'), 4);
|
|
82
|
+
return [
|
|
83
|
+
` it('${escapeSingleQuote(block.name)}', async () => {`,
|
|
84
|
+
` render(<App />)`,
|
|
85
|
+
setup,
|
|
86
|
+
indented,
|
|
87
|
+
` })`,
|
|
88
|
+
].join('\n');
|
|
89
|
+
});
|
|
90
|
+
return [`describe('${escapedName}', () => {`, ...blocks, `})`].join('\n');
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=test-template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-template.js","sourceRoot":"","sources":["../../src/templates/test-template.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript types for project conventions detection (Phase 3).
|
|
3
|
+
*/
|
|
4
|
+
export type ImportStyle = 'esm' | 'cjs';
|
|
5
|
+
export type MockPattern = 'vi.mock' | 'jest.mock' | 'none';
|
|
6
|
+
export type MockRecommendationKind = 'inline' | 'extract';
|
|
7
|
+
export type MutationLifecycleStage = 'loading' | 'success' | 'error';
|
|
8
|
+
export type MockInstabilityKind = 'recreated-factory' | 'per-test-churn';
|
|
9
|
+
export interface ConventionFile {
|
|
10
|
+
path: string;
|
|
11
|
+
importStyle: ImportStyle;
|
|
12
|
+
hasDescribeBlock: boolean;
|
|
13
|
+
mockPattern: MockPattern;
|
|
14
|
+
hasHelperWithExpect: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface ConventionsSchema {
|
|
17
|
+
scannedAt: string;
|
|
18
|
+
projectRoot: string;
|
|
19
|
+
importStyle: ImportStyle;
|
|
20
|
+
mockPattern: MockPattern;
|
|
21
|
+
testFiles: ConventionFile[];
|
|
22
|
+
folderPattern: 'colocated' | '__tests__' | 'mixed' | 'unknown';
|
|
23
|
+
fileExtension: 'ts' | 'tsx' | 'js' | 'jsx' | 'mixed';
|
|
24
|
+
}
|
|
25
|
+
export interface MockTargetUsage {
|
|
26
|
+
target: string;
|
|
27
|
+
files: string[];
|
|
28
|
+
count: number;
|
|
29
|
+
}
|
|
30
|
+
export interface MockRecommendation {
|
|
31
|
+
target: string;
|
|
32
|
+
kind: MockRecommendationKind;
|
|
33
|
+
reason: string;
|
|
34
|
+
files: string[];
|
|
35
|
+
count: number;
|
|
36
|
+
}
|
|
37
|
+
export interface MutationLifecyclePattern {
|
|
38
|
+
file: string;
|
|
39
|
+
stages: MutationLifecycleStage[];
|
|
40
|
+
evidence: string[];
|
|
41
|
+
}
|
|
42
|
+
export interface MockInstabilityWarning {
|
|
43
|
+
file: string;
|
|
44
|
+
kind: MockInstabilityKind;
|
|
45
|
+
reason: string;
|
|
46
|
+
evidence: string[];
|
|
47
|
+
}
|
|
48
|
+
export declare const DEFAULT_CONVENTIONS: ConventionsSchema;
|
|
49
|
+
//# sourceMappingURL=conventions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conventions.d.ts","sourceRoot":"","sources":["../../src/types/conventions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,KAAK,CAAA;AACvC,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,CAAA;AAC1D,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,SAAS,CAAA;AACzD,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAA;AACpE,MAAM,MAAM,mBAAmB,GAAG,mBAAmB,GAAG,gBAAgB,CAAA;AAExE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,WAAW,CAAA;IACxB,gBAAgB,EAAE,OAAO,CAAA;IACzB,WAAW,EAAE,WAAW,CAAA;IACxB,mBAAmB,EAAE,OAAO,CAAA;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,WAAW,CAAA;IACxB,WAAW,EAAE,WAAW,CAAA;IACxB,SAAS,EAAE,cAAc,EAAE,CAAA;IAC3B,aAAa,EAAE,WAAW,GAAG,WAAW,GAAG,OAAO,GAAG,SAAS,CAAA;IAC9D,aAAa,EAAE,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG,OAAO,CAAA;CACrD;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,sBAAsB,CAAA;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,sBAAsB,EAAE,CAAA;IAChC,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,mBAAmB,CAAA;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,eAAO,MAAM,mBAAmB,EAAE,iBAQjC,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript types for project conventions detection (Phase 3).
|
|
3
|
+
*/
|
|
4
|
+
export const DEFAULT_CONVENTIONS = {
|
|
5
|
+
scannedAt: '',
|
|
6
|
+
projectRoot: '',
|
|
7
|
+
importStyle: 'esm',
|
|
8
|
+
mockPattern: 'none',
|
|
9
|
+
testFiles: [],
|
|
10
|
+
folderPattern: 'unknown',
|
|
11
|
+
fileExtension: 'ts',
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=conventions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conventions.js","sourceRoot":"","sources":["../../src/types/conventions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAqDH,MAAM,CAAC,MAAM,mBAAmB,GAAsB;IACpD,SAAS,EAAE,EAAE;IACb,WAAW,EAAE,EAAE;IACf,WAAW,EAAE,KAAK;IAClB,WAAW,EAAE,MAAM;IACnB,SAAS,EAAE,EAAE;IACb,aAAa,EAAE,SAAS;IACxB,aAAa,EAAE,IAAI;CACpB,CAAA"}
|