@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 @@
|
|
|
1
|
+
{"version":3,"file":"target-analyzer.d.ts","sourceRoot":"","sources":["../../../src/analyzer/mocks/target-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,wBAAwB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,8BAA8B;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,kBAAkB;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,WAAW,EAAE,KAAK,GAAG,SAAS,GAAG,OAAO,GAAG,YAAY,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC5E,6DAA6D;IAC7D,wBAAwB,EAAE,QAAQ,GAAG,WAAW,GAAG,QAAQ,CAAC;IAC5D,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,mBAAmB;IACnB,IAAI,EAAE,KAAK,GAAG,SAAS,GAAG,OAAO,GAAG,YAAY,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrE,4BAA4B;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iCAAiC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACvC,qCAAqC;IACrC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,6BAA6B;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,WAAW,EAAE,CA8Df;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,GACzC,WAAW,EAAE,CAyDf;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,WAAW,EACpB,kBAAkB,EAAE,WAAW,EAAE,EACjC,MAAM,CAAC,EAAE,wBAAwB,GAChC,WAAW,CAAC,MAAM,CAAC,CAwCrB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,WAAW,EACpB,aAAa,EAAE,MAAM,EAAE,GACtB,QAAQ,GAAG,WAAW,GAAG,QAAQ,CAoBnC;AA0BD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,GAAE,MAAoB,GAAG,MAAM,CAiB/F;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,WAAW,EAAE,EACvB,OAAO,CAAC,EAAE;IACR,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,aAAa,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACpD,MAAM,CAAC,EAAE,wBAAwB,CAAC;CACnC,GACA,UAAU,EAAE,CAoDd;AAiCD;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,UAAU,EAAE,GACpB,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAU3B"}
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock Target Analyzer - Identifies appropriate mock targets from codebase
|
|
3
|
+
*
|
|
4
|
+
* Analyzes the codebase to determine which mock libraries are available
|
|
5
|
+
* (msw, jest.fn, sinon) and suggests appropriate mock targets based
|
|
6
|
+
* on the detected API calls.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Detect available mock libraries from package.json dependencies
|
|
10
|
+
*/
|
|
11
|
+
export function detectMockLibraries(packageJson) {
|
|
12
|
+
const libraries = [];
|
|
13
|
+
const deps = {
|
|
14
|
+
...(packageJson.dependencies || {}),
|
|
15
|
+
...(packageJson.devDependencies || {}),
|
|
16
|
+
};
|
|
17
|
+
// Detect MSW (Mock Service Worker)
|
|
18
|
+
if (deps['msw'] || deps['@mswjs/msw']) {
|
|
19
|
+
libraries.push({
|
|
20
|
+
name: 'msw',
|
|
21
|
+
version: deps['msw'] || deps['@mswjs/msw'],
|
|
22
|
+
isConfigured: false, // Would need to check for handlers setup
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
// Jest is always available in Jest projects
|
|
26
|
+
if (deps['jest']) {
|
|
27
|
+
libraries.push({
|
|
28
|
+
name: 'jest.fn',
|
|
29
|
+
version: deps['jest'],
|
|
30
|
+
isConfigured: true,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
// Sinon
|
|
34
|
+
if (deps['sinon']) {
|
|
35
|
+
libraries.push({
|
|
36
|
+
name: 'sinon',
|
|
37
|
+
version: deps['sinon'],
|
|
38
|
+
isConfigured: false,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
// fetch-mock
|
|
42
|
+
if (deps['fetch-mock']) {
|
|
43
|
+
libraries.push({
|
|
44
|
+
name: 'fetch-mock',
|
|
45
|
+
version: deps['fetch-mock'],
|
|
46
|
+
isConfigured: false,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
// undici (Node.js fetch polyfill with mocking support)
|
|
50
|
+
if (deps['undici']) {
|
|
51
|
+
libraries.push({
|
|
52
|
+
name: 'undici',
|
|
53
|
+
version: deps['undici'],
|
|
54
|
+
isConfigured: false,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
// nock
|
|
58
|
+
if (deps['nock']) {
|
|
59
|
+
libraries.push({
|
|
60
|
+
name: 'nock',
|
|
61
|
+
version: deps['nock'],
|
|
62
|
+
isConfigured: false,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return libraries;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Analyze code files to see which mock libraries are actually used
|
|
69
|
+
*/
|
|
70
|
+
export function analyzeMockLibraryUsage(files) {
|
|
71
|
+
const detected = [];
|
|
72
|
+
const seen = new Set();
|
|
73
|
+
for (const file of files) {
|
|
74
|
+
const content = file.content;
|
|
75
|
+
// Check for MSW usage
|
|
76
|
+
if (content.includes('setupWorker') || content.includes('setupMSW') || content.includes('http.get') && content.includes('msw/')) {
|
|
77
|
+
if (!seen.has('msw')) {
|
|
78
|
+
detected.push({ name: 'msw', isConfigured: true, sourceFile: file.path });
|
|
79
|
+
seen.add('msw');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Check for jest.fn() usage
|
|
83
|
+
if (content.includes('jest.fn()') || content.includes('jest.mock(') || content.includes('vi.fn()')) {
|
|
84
|
+
if (!seen.has('jest.fn')) {
|
|
85
|
+
detected.push({ name: 'jest.fn', isConfigured: true, sourceFile: file.path });
|
|
86
|
+
seen.add('jest.fn');
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// Check for sinon usage
|
|
90
|
+
if (content.includes('sinon.stub') || content.includes('sinon.spy') || content.includes('sinon.mock')) {
|
|
91
|
+
if (!seen.has('sinon')) {
|
|
92
|
+
detected.push({ name: 'sinon', isConfigured: true, sourceFile: file.path });
|
|
93
|
+
seen.add('sinon');
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Check for fetch-mock
|
|
97
|
+
if (content.includes('fetchMock') || content.includes('fetch-mock')) {
|
|
98
|
+
if (!seen.has('fetch-mock')) {
|
|
99
|
+
detected.push({ name: 'fetch-mock', isConfigured: true, sourceFile: file.path });
|
|
100
|
+
seen.add('fetch-mock');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Check for undici
|
|
104
|
+
if (content.includes('MockAgent') && content.includes('undici')) {
|
|
105
|
+
if (!seen.has('undici')) {
|
|
106
|
+
detected.push({ name: 'undici', isConfigured: true, sourceFile: file.path });
|
|
107
|
+
seen.add('undici');
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Check for nock
|
|
111
|
+
if (content.includes('nock(') || content.includes('nock.recorder')) {
|
|
112
|
+
if (!seen.has('nock')) {
|
|
113
|
+
detected.push({ name: 'nock', isConfigured: true, sourceFile: file.path });
|
|
114
|
+
seen.add('nock');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return detected;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Determine the best mock library for a given API call
|
|
122
|
+
*/
|
|
123
|
+
export function selectMockLibrary(apiCall, availableLibraries, config) {
|
|
124
|
+
// If preferred library is available, use it
|
|
125
|
+
if (config?.preferredLibrary) {
|
|
126
|
+
const preferred = availableLibraries.find(l => l.name === config.preferredLibrary);
|
|
127
|
+
if (preferred) {
|
|
128
|
+
return preferred.name;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// For external APIs, prefer MSW or fetch-mock for HTTP mocking
|
|
132
|
+
if (apiCall.method === 'fetch' || apiCall.method === 'axios') {
|
|
133
|
+
// Prefer MSW for REST APIs
|
|
134
|
+
if (availableLibraries.find(l => l.name === 'msw')) {
|
|
135
|
+
return 'msw';
|
|
136
|
+
}
|
|
137
|
+
// Fall back to fetch-mock
|
|
138
|
+
if (availableLibraries.find(l => l.name === 'fetch-mock')) {
|
|
139
|
+
return 'fetch-mock';
|
|
140
|
+
}
|
|
141
|
+
// Fall back to nock
|
|
142
|
+
if (availableLibraries.find(l => l.name === 'nock')) {
|
|
143
|
+
return 'nock';
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// For XMLHttpRequest, prefer sinon or jest.fn
|
|
147
|
+
if (apiCall.method === 'XMLHttpRequest') {
|
|
148
|
+
if (availableLibraries.find(l => l.name === 'sinon')) {
|
|
149
|
+
return 'sinon';
|
|
150
|
+
}
|
|
151
|
+
return 'jest.fn';
|
|
152
|
+
}
|
|
153
|
+
// Default to jest.fn if nothing else available
|
|
154
|
+
if (availableLibraries.find(l => l.name === 'jest.fn')) {
|
|
155
|
+
return 'jest.fn';
|
|
156
|
+
}
|
|
157
|
+
// Fallback
|
|
158
|
+
return 'jest.fn';
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Decide whether to inline or extract a mock
|
|
162
|
+
*/
|
|
163
|
+
export function decideMockExtraction(apiCall, existingMocks) {
|
|
164
|
+
// Check if there's already a mock for this URL
|
|
165
|
+
const hasExistingMock = existingMocks.some(mock => mock.includes(apiCall.url || ''));
|
|
166
|
+
if (hasExistingMock) {
|
|
167
|
+
return 'shared';
|
|
168
|
+
}
|
|
169
|
+
// External APIs should typically be extracted
|
|
170
|
+
if (apiCall.isExternal) {
|
|
171
|
+
return 'extracted';
|
|
172
|
+
}
|
|
173
|
+
// Complex responses should be extracted
|
|
174
|
+
const complexity = estimateMockComplexity(apiCall);
|
|
175
|
+
if (complexity > 10) {
|
|
176
|
+
return 'extracted';
|
|
177
|
+
}
|
|
178
|
+
// Default to inline for simple cases
|
|
179
|
+
return 'inline';
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Estimate the complexity of a mock (lines of code)
|
|
183
|
+
*/
|
|
184
|
+
function estimateMockComplexity(apiCall) {
|
|
185
|
+
let complexity = 1;
|
|
186
|
+
// URL parameters increase complexity
|
|
187
|
+
if (apiCall.url?.includes('?')) {
|
|
188
|
+
complexity += 2;
|
|
189
|
+
}
|
|
190
|
+
// POST/PUT/PATCH methods typically have request bodies
|
|
191
|
+
if (apiCall.httpMethod === 'POST' || apiCall.httpMethod === 'PUT' || apiCall.httpMethod === 'PATCH') {
|
|
192
|
+
complexity += 3;
|
|
193
|
+
}
|
|
194
|
+
// External APIs might need more sophisticated mocking
|
|
195
|
+
if (apiCall.isExternal) {
|
|
196
|
+
complexity += 2;
|
|
197
|
+
}
|
|
198
|
+
return complexity;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Generate suggested file path for extracted mock
|
|
202
|
+
*/
|
|
203
|
+
export function suggestMockFilePath(apiCall, baseDir = '__mocks__') {
|
|
204
|
+
if (!apiCall.url) {
|
|
205
|
+
return `${baseDir}/api-mock.ts`;
|
|
206
|
+
}
|
|
207
|
+
try {
|
|
208
|
+
const url = new URL(apiCall.url);
|
|
209
|
+
const pathParts = url.pathname.split('/').filter(Boolean);
|
|
210
|
+
// Clean up path parts for file names
|
|
211
|
+
const fileName = pathParts.join('-') || 'index';
|
|
212
|
+
const cleanFileName = fileName.replace(/[^a-zA-Z0-9-]/g, '-').toLowerCase();
|
|
213
|
+
return `${baseDir}/${url.hostname}/${cleanFileName}.ts`;
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
return `${baseDir}/api-mock.ts`;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Main function to analyze mock targets
|
|
221
|
+
*/
|
|
222
|
+
export function analyzeMockTargets(apiCalls, options) {
|
|
223
|
+
const targets = [];
|
|
224
|
+
// Detect available mock libraries
|
|
225
|
+
let availableLibraries = [];
|
|
226
|
+
if (options?.packageJson) {
|
|
227
|
+
availableLibraries = detectMockLibraries(options.packageJson);
|
|
228
|
+
}
|
|
229
|
+
if (options?.codebaseFiles) {
|
|
230
|
+
const usedLibraries = analyzeMockLibraryUsage(options.codebaseFiles);
|
|
231
|
+
// Merge with package.json detections, preferring configured ones
|
|
232
|
+
for (const lib of usedLibraries) {
|
|
233
|
+
const existing = availableLibraries.find(l => l.name === lib.name);
|
|
234
|
+
if (!existing) {
|
|
235
|
+
availableLibraries.push(lib);
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
existing.isConfigured = lib.isConfigured || existing.isConfigured;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
// If no libraries detected, default to jest.fn
|
|
243
|
+
if (availableLibraries.length === 0) {
|
|
244
|
+
availableLibraries.push({ name: 'jest.fn', isConfigured: true });
|
|
245
|
+
}
|
|
246
|
+
// Get existing mock files (simple heuristic)
|
|
247
|
+
const existingMocks = options?.codebaseFiles
|
|
248
|
+
?.filter(f => f.path.includes('__mocks__') || f.path.includes('.mock.'))
|
|
249
|
+
.map(f => f.path) || [];
|
|
250
|
+
// Analyze each API call
|
|
251
|
+
for (const apiCall of apiCalls) {
|
|
252
|
+
const mockLibrary = selectMockLibrary(apiCall, availableLibraries, options?.config);
|
|
253
|
+
const extraction = decideMockExtraction(apiCall, existingMocks);
|
|
254
|
+
const suggestedPath = extraction !== 'inline' ? suggestMockFilePath(apiCall) : undefined;
|
|
255
|
+
targets.push({
|
|
256
|
+
id: `mock-target-${apiCall.id}`,
|
|
257
|
+
apiCallId: apiCall.id,
|
|
258
|
+
url: apiCall.url || 'unknown',
|
|
259
|
+
method: apiCall.httpMethod || 'GET',
|
|
260
|
+
mockLibrary,
|
|
261
|
+
extractionRecommendation: extraction,
|
|
262
|
+
rationale: buildRationale(apiCall, mockLibrary, extraction, availableLibraries),
|
|
263
|
+
suggestedFilePath: suggestedPath,
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
return targets;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Build a rationale string for the mock decision
|
|
270
|
+
*/
|
|
271
|
+
function buildRationale(apiCall, library, extraction, availableLibraries) {
|
|
272
|
+
const parts = [];
|
|
273
|
+
// Library choice rationale
|
|
274
|
+
const libInfo = availableLibraries.find(l => l.name === library);
|
|
275
|
+
if (libInfo?.isConfigured) {
|
|
276
|
+
parts.push(`Using ${library} (already configured in project)`);
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
parts.push(`Using ${library} (detected in dependencies)`);
|
|
280
|
+
}
|
|
281
|
+
// Extraction rationale
|
|
282
|
+
if (extraction === 'inline') {
|
|
283
|
+
parts.push('inline for simplicity (simple mock)');
|
|
284
|
+
}
|
|
285
|
+
else if (extraction === 'extracted') {
|
|
286
|
+
parts.push('extracted to separate file (complex/external API)');
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
parts.push('reusing existing mock (shared)');
|
|
290
|
+
}
|
|
291
|
+
return parts.join('. ');
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Group mock targets by recommended approach
|
|
295
|
+
*/
|
|
296
|
+
export function groupMockTargetsByApproach(targets) {
|
|
297
|
+
const groups = new Map();
|
|
298
|
+
for (const target of targets) {
|
|
299
|
+
const key = `${target.mockLibrary}:${target.extractionRecommendation}`;
|
|
300
|
+
const existing = groups.get(key) || [];
|
|
301
|
+
groups.set(key, [...existing, target]);
|
|
302
|
+
}
|
|
303
|
+
return groups;
|
|
304
|
+
}
|
|
305
|
+
//# sourceMappingURL=target-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"target-analyzer.js","sourceRoot":"","sources":["../../../src/analyzer/mocks/target-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAoDH;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,WAAoC;IAEpC,MAAM,SAAS,GAAkB,EAAE,CAAC;IACpC,MAAM,IAAI,GAAG;QACX,GAAG,CAAC,WAAW,CAAC,YAAsC,IAAI,EAAE,CAAC;QAC7D,GAAG,CAAC,WAAW,CAAC,eAAyC,IAAI,EAAE,CAAC;KACjE,CAAC;IAEF,mCAAmC;IACnC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;QACtC,SAAS,CAAC,IAAI,CAAC;YACb,IAAI,EAAE,KAAK;YACX,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC;YAC1C,YAAY,EAAE,KAAK,EAAE,yCAAyC;SAC/D,CAAC,CAAC;IACL,CAAC;IAED,4CAA4C;IAC5C,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACjB,SAAS,CAAC,IAAI,CAAC;YACb,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC;YACrB,YAAY,EAAE,IAAI;SACnB,CAAC,CAAC;IACL,CAAC;IAED,QAAQ;IACR,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAClB,SAAS,CAAC,IAAI,CAAC;YACb,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC;YACtB,YAAY,EAAE,KAAK;SACpB,CAAC,CAAC;IACL,CAAC;IAED,aAAa;IACb,IAAI,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;QACvB,SAAS,CAAC,IAAI,CAAC;YACb,IAAI,EAAE,YAAY;YAClB,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC;YAC3B,YAAY,EAAE,KAAK;SACpB,CAAC,CAAC;IACL,CAAC;IAED,uDAAuD;IACvD,IAAI,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnB,SAAS,CAAC,IAAI,CAAC;YACb,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC;YACvB,YAAY,EAAE,KAAK;SACpB,CAAC,CAAC;IACL,CAAC;IAED,OAAO;IACP,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACjB,SAAS,CAAC,IAAI,CAAC;YACb,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC;YACrB,YAAY,EAAE,KAAK;SACpB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CACrC,KAA0C;IAE1C,MAAM,QAAQ,GAAkB,EAAE,CAAC;IACnC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAE7B,sBAAsB;QACtB,IAAI,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAChI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC1E,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,4BAA4B;QAC5B,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACnG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC9E,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;QAED,wBAAwB;QACxB,IAAI,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YACtG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC5E,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACpB,CAAC;QACH,CAAC;QAED,uBAAuB;QACvB,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YACpE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBACjF,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;QAED,mBAAmB;QACnB,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAChE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC7E,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;QAED,iBAAiB;QACjB,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;YACnE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC3E,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACnB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAAoB,EACpB,kBAAiC,EACjC,MAAiC;IAEjC,4CAA4C;IAC5C,IAAI,MAAM,EAAE,gBAAgB,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,gBAAgB,CAAC,CAAC;QACnF,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,SAAS,CAAC,IAAI,CAAC;QACxB,CAAC;IACH,CAAC;IAED,+DAA+D;IAC/D,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QAC7D,2BAA2B;QAC3B,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YACnD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,0BAA0B;QAC1B,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,EAAE,CAAC;YAC1D,OAAO,YAAY,CAAC;QACtB,CAAC;QACD,oBAAoB;QACpB,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,EAAE,CAAC;YACpD,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAED,8CAA8C;IAC9C,IAAI,OAAO,CAAC,MAAM,KAAK,gBAAgB,EAAE,CAAC;QACxC,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,EAAE,CAAC;YACrD,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,+CAA+C;IAC/C,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,EAAE,CAAC;QACvD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,WAAW;IACX,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAAoB,EACpB,aAAuB;IAEvB,+CAA+C;IAC/C,MAAM,eAAe,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;IACrF,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,8CAA8C;IAC9C,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,wCAAwC;IACxC,MAAM,UAAU,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;IACnD,IAAI,UAAU,GAAG,EAAE,EAAE,CAAC;QACpB,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,qCAAqC;IACrC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,SAAS,sBAAsB,CAAC,OAAoB;IAClD,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,qCAAqC;IACrC,IAAI,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/B,UAAU,IAAI,CAAC,CAAC;IAClB,CAAC;IAED,uDAAuD;IACvD,IAAI,OAAO,CAAC,UAAU,KAAK,MAAM,IAAI,OAAO,CAAC,UAAU,KAAK,KAAK,IAAI,OAAO,CAAC,UAAU,KAAK,OAAO,EAAE,CAAC;QACpG,UAAU,IAAI,CAAC,CAAC;IAClB,CAAC;IAED,sDAAsD;IACtD,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,UAAU,IAAI,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAoB,EAAE,UAAkB,WAAW;IACrF,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QACjB,OAAO,GAAG,OAAO,cAAc,CAAC;IAClC,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAE1D,qCAAqC;QACrC,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC;QAChD,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAE5E,OAAO,GAAG,OAAO,IAAI,GAAG,CAAC,QAAQ,IAAI,aAAa,KAAK,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,OAAO,cAAc,CAAC;IAClC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,QAAuB,EACvB,OAIC;IAED,MAAM,OAAO,GAAiB,EAAE,CAAC;IAEjC,kCAAkC;IAClC,IAAI,kBAAkB,GAAkB,EAAE,CAAC;IAE3C,IAAI,OAAO,EAAE,WAAW,EAAE,CAAC;QACzB,kBAAkB,GAAG,mBAAmB,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAChE,CAAC;IAED,IAAI,OAAO,EAAE,aAAa,EAAE,CAAC;QAC3B,MAAM,aAAa,GAAG,uBAAuB,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QACrE,iEAAiE;QACjE,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;YAChC,MAAM,QAAQ,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC;YACnE,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,YAAY,GAAG,GAAG,CAAC,YAAY,IAAI,QAAQ,CAAC,YAAY,CAAC;YACpE,CAAC;QACH,CAAC;IACH,CAAC;IAED,+CAA+C;IAC/C,IAAI,kBAAkB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpC,kBAAkB,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,6CAA6C;IAC7C,MAAM,aAAa,GAAG,OAAO,EAAE,aAAa;QAC1C,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;SACvE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAE1B,wBAAwB;IACxB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,WAAW,GAAG,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QACpF,MAAM,UAAU,GAAG,oBAAoB,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;QAChE,MAAM,aAAa,GAAG,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAEzF,OAAO,CAAC,IAAI,CAAC;YACX,EAAE,EAAE,eAAe,OAAO,CAAC,EAAE,EAAE;YAC/B,SAAS,EAAE,OAAO,CAAC,EAAE;YACrB,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,SAAS;YAC7B,MAAM,EAAE,OAAO,CAAC,UAAU,IAAI,KAAK;YACnC,WAAW;YACX,wBAAwB,EAAE,UAAU;YACpC,SAAS,EAAE,cAAc,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,kBAAkB,CAAC;YAC/E,iBAAiB,EAAE,aAAa;SACjC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CACrB,OAAoB,EACpB,OAA4B,EAC5B,UAA6C,EAC7C,kBAAiC;IAEjC,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,2BAA2B;IAC3B,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;IACjE,IAAI,OAAO,EAAE,YAAY,EAAE,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC,SAAS,OAAO,kCAAkC,CAAC,CAAC;IACjE,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,SAAS,OAAO,6BAA6B,CAAC,CAAC;IAC5D,CAAC;IAED,uBAAuB;IACvB,IAAI,UAAU,KAAK,QAAQ,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;IACpD,CAAC;SAAM,IAAI,UAAU,KAAK,WAAW,EAAE,CAAC;QACtC,KAAK,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;IAClE,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,0BAA0B,CACxC,OAAqB;IAErB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAwB,CAAC;IAE/C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,wBAAwB,EAAE,CAAC;QACvE,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACvC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;IACzC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Page } from 'playwright';
|
|
2
|
+
/**
|
|
3
|
+
* Query strategy for Testing Library
|
|
4
|
+
*/
|
|
5
|
+
export interface QueryStrategy {
|
|
6
|
+
method: string;
|
|
7
|
+
args: (string | RegExp | {
|
|
8
|
+
name?: string;
|
|
9
|
+
exact?: boolean;
|
|
10
|
+
})[];
|
|
11
|
+
priority: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Accessibility properties extracted from an element
|
|
15
|
+
*/
|
|
16
|
+
export interface AccessibilityProperties {
|
|
17
|
+
preferredQuery: QueryStrategy;
|
|
18
|
+
alternatives: QueryStrategy[];
|
|
19
|
+
hasAccessibleName: boolean;
|
|
20
|
+
isInteractive: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Analyzes an element's accessibility properties and suggests optimal Testing Library queries
|
|
24
|
+
* @param page - The Playwright page object
|
|
25
|
+
* @param selector - CSS selector for the element
|
|
26
|
+
* @returns Promise<AccessibilityProperties> - Analysis results with ranked query strategies
|
|
27
|
+
*/
|
|
28
|
+
export declare function analyzeElementProperties(page: Page, selector: string): Promise<AccessibilityProperties | null>;
|
|
29
|
+
/**
|
|
30
|
+
* Gets all interactive elements on the page with their query strategies
|
|
31
|
+
* @param page - The Playwright page object
|
|
32
|
+
* @returns Promise<Array<{ selector: string; properties: AccessibilityProperties }>>
|
|
33
|
+
*/
|
|
34
|
+
export declare function analyzePageElements(page: Page): Promise<Array<{
|
|
35
|
+
selector: string;
|
|
36
|
+
properties: AccessibilityProperties;
|
|
37
|
+
}>>;
|
|
38
|
+
/**
|
|
39
|
+
* Recommends the best query method for a given element
|
|
40
|
+
* @param properties - The accessibility properties
|
|
41
|
+
* @returns string - Recommended query method
|
|
42
|
+
*/
|
|
43
|
+
export declare function recommendQueryMethod(properties: AccessibilityProperties): string;
|
|
44
|
+
//# sourceMappingURL=element-analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"element-analyzer.d.ts","sourceRoot":"","sources":["../../../src/analyzer/visual/element-analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGlC;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,EAAE,CAAC;IAC/D,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,cAAc,EAAE,aAAa,CAAC;IAC9B,YAAY,EAAE,aAAa,EAAE,CAAC;IAC9B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAgIzC;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,IAAI,GACT,OAAO,CAAC,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,uBAAuB,CAAA;CAAE,CAAC,CAAC,CAkC3E;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,uBAAuB,GAAG,MAAM,CAkBhF"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { inspectElement } from './inspector.js';
|
|
2
|
+
/**
|
|
3
|
+
* Analyzes an element's accessibility properties and suggests optimal Testing Library queries
|
|
4
|
+
* @param page - The Playwright page object
|
|
5
|
+
* @param selector - CSS selector for the element
|
|
6
|
+
* @returns Promise<AccessibilityProperties> - Analysis results with ranked query strategies
|
|
7
|
+
*/
|
|
8
|
+
export async function analyzeElementProperties(page, selector) {
|
|
9
|
+
const elementInfo = await inspectElement(page, selector);
|
|
10
|
+
if (!elementInfo) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
const strategies = [];
|
|
14
|
+
const tagName = elementInfo.tagName.toLowerCase();
|
|
15
|
+
// Determine if element is interactive
|
|
16
|
+
const interactiveRoles = [
|
|
17
|
+
'button', 'link', 'menuitem', 'checkbox', 'radio', 'switch',
|
|
18
|
+
'textbox', 'searchbox', 'combobox', 'slider', 'spinbutton'
|
|
19
|
+
];
|
|
20
|
+
const isInteractive = interactiveRoles.includes(elementInfo.ariaRole || '') ||
|
|
21
|
+
['button', 'a', 'input', 'select', 'textarea'].includes(tagName);
|
|
22
|
+
// 1. getByRole + name (most robust)
|
|
23
|
+
if (elementInfo.ariaRole && elementInfo.textContent) {
|
|
24
|
+
strategies.push({
|
|
25
|
+
method: 'getByRole',
|
|
26
|
+
args: [elementInfo.ariaRole, { name: elementInfo.textContent }],
|
|
27
|
+
priority: 1,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
// 2. getByLabelText (form fields)
|
|
31
|
+
const labelFor = await page.$eval(selector, (el) => {
|
|
32
|
+
const htmlEl = el;
|
|
33
|
+
if (htmlEl.id) {
|
|
34
|
+
const label = document.querySelector(`label[for="${htmlEl.id}"]`);
|
|
35
|
+
return label?.textContent?.trim() || null;
|
|
36
|
+
}
|
|
37
|
+
// Check parent label
|
|
38
|
+
const parentLabel = htmlEl.closest('label');
|
|
39
|
+
return parentLabel?.textContent?.trim() || null;
|
|
40
|
+
}).catch(() => null);
|
|
41
|
+
if (labelFor) {
|
|
42
|
+
strategies.push({
|
|
43
|
+
method: 'getByLabelText',
|
|
44
|
+
args: [labelFor],
|
|
45
|
+
priority: 2,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
// Also check for aria-label
|
|
49
|
+
if (elementInfo.ariaLabel) {
|
|
50
|
+
strategies.push({
|
|
51
|
+
method: 'getByLabelText',
|
|
52
|
+
args: [elementInfo.ariaLabel],
|
|
53
|
+
priority: 2,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
// 3. getByPlaceholderText
|
|
57
|
+
const placeholder = await page.$eval(selector, (el) => {
|
|
58
|
+
return el.placeholder || '';
|
|
59
|
+
}).catch(() => '');
|
|
60
|
+
if (placeholder) {
|
|
61
|
+
strategies.push({
|
|
62
|
+
method: 'getByPlaceholderText',
|
|
63
|
+
args: [placeholder, { exact: true }],
|
|
64
|
+
priority: 3,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
// 4. getByAltText (images)
|
|
68
|
+
if (tagName === 'img') {
|
|
69
|
+
const altText = await page.$eval(selector, (el) => {
|
|
70
|
+
return el.alt || '';
|
|
71
|
+
}).catch(() => '');
|
|
72
|
+
if (altText) {
|
|
73
|
+
strategies.push({
|
|
74
|
+
method: 'getByAltText',
|
|
75
|
+
args: [altText],
|
|
76
|
+
priority: 4,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// 5. getByTestId (if data-testid present)
|
|
81
|
+
const testId = await page.$eval(selector, (el) => {
|
|
82
|
+
return el.getAttribute('data-testid') || el.getAttribute('data-test-id') || '';
|
|
83
|
+
}).catch(() => '');
|
|
84
|
+
if (testId) {
|
|
85
|
+
strategies.push({
|
|
86
|
+
method: 'getByTestId',
|
|
87
|
+
args: [testId],
|
|
88
|
+
priority: 5,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
// 6. getByText (last resort)
|
|
92
|
+
if (elementInfo.textContent) {
|
|
93
|
+
strategies.push({
|
|
94
|
+
method: 'getByText',
|
|
95
|
+
args: [elementInfo.textContent, { exact: true }],
|
|
96
|
+
priority: 6,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
// Sort by priority
|
|
100
|
+
strategies.sort((a, b) => a.priority - b.priority);
|
|
101
|
+
// Check if element has accessible name
|
|
102
|
+
const hasAccessibleName = !!(elementInfo.ariaLabel ||
|
|
103
|
+
elementInfo.textContent ||
|
|
104
|
+
labelFor ||
|
|
105
|
+
placeholder ||
|
|
106
|
+
testId);
|
|
107
|
+
return {
|
|
108
|
+
preferredQuery: strategies[0] || {
|
|
109
|
+
method: 'getByRole',
|
|
110
|
+
args: ['generic'],
|
|
111
|
+
priority: 99,
|
|
112
|
+
},
|
|
113
|
+
alternatives: strategies.slice(1),
|
|
114
|
+
hasAccessibleName,
|
|
115
|
+
isInteractive,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Gets all interactive elements on the page with their query strategies
|
|
120
|
+
* @param page - The Playwright page object
|
|
121
|
+
* @returns Promise<Array<{ selector: string; properties: AccessibilityProperties }>>
|
|
122
|
+
*/
|
|
123
|
+
export async function analyzePageElements(page) {
|
|
124
|
+
const results = [];
|
|
125
|
+
// Find common interactive element selectors
|
|
126
|
+
const selectors = [
|
|
127
|
+
'button', 'a', 'input', 'select', 'textarea',
|
|
128
|
+
'[role="button"]', '[role="link"]', '[role="checkbox"]',
|
|
129
|
+
'[role="radio"]', '[role="textbox"]'
|
|
130
|
+
];
|
|
131
|
+
for (const sel of selectors) {
|
|
132
|
+
const elements = await page.$$(sel);
|
|
133
|
+
for (const element of elements) {
|
|
134
|
+
const selector = await element.evaluate((el) => {
|
|
135
|
+
// Generate a unique selector
|
|
136
|
+
if (el.id)
|
|
137
|
+
return `#${el.id}`;
|
|
138
|
+
if (el.getAttribute('data-testid'))
|
|
139
|
+
return `[data-testid="${el.getAttribute('data-testid')}"]`;
|
|
140
|
+
if (el.className && typeof el.className === 'object' && 'baseVal' in el.className) {
|
|
141
|
+
return el.tagName.toLowerCase();
|
|
142
|
+
}
|
|
143
|
+
const classList = el.classList ? Array.from(el.classList) : [];
|
|
144
|
+
const classes = classList.filter((c) => !c.includes('Mui')).join('.');
|
|
145
|
+
return classes ? `${el.tagName.toLowerCase()}.${classes}` : el.tagName.toLowerCase();
|
|
146
|
+
});
|
|
147
|
+
const properties = await analyzeElementProperties(page, sel);
|
|
148
|
+
if (properties) {
|
|
149
|
+
results.push({ selector, properties });
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return results;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Recommends the best query method for a given element
|
|
157
|
+
* @param properties - The accessibility properties
|
|
158
|
+
* @returns string - Recommended query method
|
|
159
|
+
*/
|
|
160
|
+
export function recommendQueryMethod(properties) {
|
|
161
|
+
const { preferredQuery } = properties;
|
|
162
|
+
if (preferredQuery.priority === 99) {
|
|
163
|
+
return `// Warning: No good query strategy found. Consider adding data-testid or aria-label.`;
|
|
164
|
+
}
|
|
165
|
+
let queryString = preferredQuery.method;
|
|
166
|
+
if (preferredQuery.args.length > 0) {
|
|
167
|
+
const args = preferredQuery.args.map(arg => {
|
|
168
|
+
if (arg instanceof RegExp)
|
|
169
|
+
return `/${arg.source}/${arg.flags}`;
|
|
170
|
+
return typeof arg === 'string' ? `"${arg}"` : JSON.stringify(arg);
|
|
171
|
+
}).join(', ');
|
|
172
|
+
queryString += `(${args})`;
|
|
173
|
+
}
|
|
174
|
+
return queryString;
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=element-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"element-analyzer.js","sourceRoot":"","sources":["../../../src/analyzer/visual/element-analyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Browser, Page } from 'playwright';
|
|
2
|
+
/**
|
|
3
|
+
* Element information extracted from the DOM
|
|
4
|
+
*/
|
|
5
|
+
export interface ElementInfo {
|
|
6
|
+
tagName: string;
|
|
7
|
+
textContent: string;
|
|
8
|
+
ariaRole?: string;
|
|
9
|
+
ariaLabel?: string;
|
|
10
|
+
nameAttr?: string;
|
|
11
|
+
id: string;
|
|
12
|
+
classes: string[];
|
|
13
|
+
isVisible: boolean;
|
|
14
|
+
isDisabled: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Launches a headless Chromium browser
|
|
18
|
+
* @returns Promise<Browser> - The launched browser instance
|
|
19
|
+
* @throws Error if Playwright is not installed
|
|
20
|
+
*/
|
|
21
|
+
export declare function launchBrowser(): Promise<Browser>;
|
|
22
|
+
/**
|
|
23
|
+
* Captures a screenshot of the current page
|
|
24
|
+
* @param page - The Playwright page object
|
|
25
|
+
* @param path - The file path to save the screenshot
|
|
26
|
+
*/
|
|
27
|
+
export declare function captureScreenshot(page: Page, path: string): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Inspects an element by selector and extracts accessibility properties
|
|
30
|
+
* @param page - The Playwright page object
|
|
31
|
+
* @param selector - CSS selector for the element
|
|
32
|
+
* @returns Promise<ElementInfo | null> - Element info or null if not found
|
|
33
|
+
*/
|
|
34
|
+
export declare function inspectElement(page: Page, selector: string): Promise<ElementInfo | null>;
|
|
35
|
+
/**
|
|
36
|
+
* Navigates to a URL with timeout handling
|
|
37
|
+
* @param page - The Playwright page object
|
|
38
|
+
* @param url - The URL to navigate to
|
|
39
|
+
* @param timeout - Timeout in milliseconds (default 30000)
|
|
40
|
+
* @returns Promise<boolean> - True if navigation succeeded
|
|
41
|
+
*/
|
|
42
|
+
export declare function navigateToUrl(page: Page, url: string, timeout?: number): Promise<boolean>;
|
|
43
|
+
/**
|
|
44
|
+
* Gets accessibility tree for the page
|
|
45
|
+
* @param page - The Playwright page object
|
|
46
|
+
* @returns Promise<string> - Accessibility tree snapshot
|
|
47
|
+
*/
|
|
48
|
+
export declare function getAccessibilityTree(page: Page): Promise<string>;
|
|
49
|
+
//# sourceMappingURL=inspector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspector.d.ts","sourceRoot":"","sources":["../../../src/analyzer/visual/inspector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAY,MAAM,YAAY,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAWtD;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAK/E;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAiD7B;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,IAAI,EACV,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,MAAc,GACtB,OAAO,CAAC,OAAO,CAAC,CAUlB;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAKtE"}
|