@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,109 @@
|
|
|
1
|
+
import { chromium } from 'playwright';
|
|
2
|
+
/**
|
|
3
|
+
* Launches a headless Chromium browser
|
|
4
|
+
* @returns Promise<Browser> - The launched browser instance
|
|
5
|
+
* @throws Error if Playwright is not installed
|
|
6
|
+
*/
|
|
7
|
+
export async function launchBrowser() {
|
|
8
|
+
try {
|
|
9
|
+
const browser = await chromium.launch({
|
|
10
|
+
headless: true,
|
|
11
|
+
});
|
|
12
|
+
return browser;
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
throw new Error('Playwright browser not available. Install with: npx playwright install chromium');
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Captures a screenshot of the current page
|
|
20
|
+
* @param page - The Playwright page object
|
|
21
|
+
* @param path - The file path to save the screenshot
|
|
22
|
+
*/
|
|
23
|
+
export async function captureScreenshot(page, path) {
|
|
24
|
+
await page.screenshot({
|
|
25
|
+
path,
|
|
26
|
+
fullPage: true,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Inspects an element by selector and extracts accessibility properties
|
|
31
|
+
* @param page - The Playwright page object
|
|
32
|
+
* @param selector - CSS selector for the element
|
|
33
|
+
* @returns Promise<ElementInfo | null> - Element info or null if not found
|
|
34
|
+
*/
|
|
35
|
+
export async function inspectElement(page, selector) {
|
|
36
|
+
try {
|
|
37
|
+
const element = await page.$(selector);
|
|
38
|
+
if (!element) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
// Extract element properties
|
|
42
|
+
const elementInfo = await element.evaluate((el) => {
|
|
43
|
+
const computedStyle = window.getComputedStyle(el);
|
|
44
|
+
const isVisible = computedStyle.display !== 'none' &&
|
|
45
|
+
computedStyle.visibility !== 'hidden' &&
|
|
46
|
+
computedStyle.opacity !== '0';
|
|
47
|
+
// Handle className (can be string or SVGAnimatedString)
|
|
48
|
+
let classes = [];
|
|
49
|
+
const className = el.className;
|
|
50
|
+
if (typeof className === 'string') {
|
|
51
|
+
classes = className.split(' ').filter(c => c.trim().length > 0);
|
|
52
|
+
}
|
|
53
|
+
else if (className && typeof className === 'object' && 'baseVal' in className) {
|
|
54
|
+
classes = className.baseVal.split(' ').filter(c => c.trim().length > 0);
|
|
55
|
+
}
|
|
56
|
+
// Check if element is disabled
|
|
57
|
+
let isDisabled = false;
|
|
58
|
+
const htmlEl = el;
|
|
59
|
+
if (htmlEl.disabled !== undefined && (htmlEl.tagName === 'INPUT' || htmlEl.tagName === 'BUTTON' || htmlEl.tagName === 'SELECT' || htmlEl.tagName === 'TEXTAREA')) {
|
|
60
|
+
isDisabled = Boolean(htmlEl.disabled);
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
tagName: el.tagName.toLowerCase(),
|
|
64
|
+
textContent: el.textContent?.trim() || '',
|
|
65
|
+
ariaRole: el.getAttribute('role') || undefined,
|
|
66
|
+
ariaLabel: el.getAttribute('aria-label') || undefined,
|
|
67
|
+
nameAttr: el.getAttribute('name') || undefined,
|
|
68
|
+
id: el.id || '',
|
|
69
|
+
classes,
|
|
70
|
+
isVisible,
|
|
71
|
+
isDisabled,
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
return elementInfo;
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
// Element not found - return null as per spec
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Navigates to a URL with timeout handling
|
|
83
|
+
* @param page - The Playwright page object
|
|
84
|
+
* @param url - The URL to navigate to
|
|
85
|
+
* @param timeout - Timeout in milliseconds (default 30000)
|
|
86
|
+
* @returns Promise<boolean> - True if navigation succeeded
|
|
87
|
+
*/
|
|
88
|
+
export async function navigateToUrl(page, url, timeout = 30000) {
|
|
89
|
+
try {
|
|
90
|
+
await page.goto(url, { timeout, waitUntil: 'domcontentloaded' });
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
throw new Error(`Failed to load URL "${url}" after ${timeout}ms. ` +
|
|
95
|
+
'Ensure the app is running and the URL is correct.');
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Gets accessibility tree for the page
|
|
100
|
+
* @param page - The Playwright page object
|
|
101
|
+
* @returns Promise<string> - Accessibility tree snapshot
|
|
102
|
+
*/
|
|
103
|
+
export async function getAccessibilityTree(page) {
|
|
104
|
+
// Use Playwright's accessibility API
|
|
105
|
+
// @ts-expect-error - Playwright accessibility is available on CDPPage
|
|
106
|
+
const snapshot = await page.accessibility.snapshot();
|
|
107
|
+
return JSON.stringify(snapshot, null, 2);
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=inspector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspector.js","sourceRoot":"","sources":["../../../src/analyzer/visual/inspector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate command
|
|
3
|
+
* Full pipeline: parse → validate → generate → write
|
|
4
|
+
* Converts Chrome Recorder exports into React Testing Library test files.
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from 'commander';
|
|
7
|
+
export interface GenerateOptions {
|
|
8
|
+
output?: string;
|
|
9
|
+
dryRun?: boolean;
|
|
10
|
+
force?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare function createGenerateCommand(): Command;
|
|
13
|
+
//# sourceMappingURL=generate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/generate.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAwCnC,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAiQD,wBAAgB,qBAAqB,IAAI,OAAO,CA4P/C"}
|
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate command
|
|
3
|
+
* Full pipeline: parse → validate → generate → write
|
|
4
|
+
* Converts Chrome Recorder exports into React Testing Library test files.
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from 'commander';
|
|
7
|
+
import { access, mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
8
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
9
|
+
import { cwd } from 'node:process';
|
|
10
|
+
import pc from 'picocolors';
|
|
11
|
+
import { validateRecording, formatValidationErrors } from '../../core/validator.js';
|
|
12
|
+
import { parseRecording } from '../../core/parser.js';
|
|
13
|
+
import { generateTest } from '../../core/generator.js';
|
|
14
|
+
import { writeTestFile } from '../../core/writer.js';
|
|
15
|
+
import { parseJsRecording } from '../../core/js-parser.js';
|
|
16
|
+
import { captureVisualState, inspectElements, buildQuery, selectMatcher, emitQry03Warning, } from '../../core/resolver.js';
|
|
17
|
+
import { scoreGeneratedTest } from '../../core/scorer.js';
|
|
18
|
+
import { verifySyntax } from '../../core/verifier.js';
|
|
19
|
+
import { analyzeSingleTestFile, mergeConventions, readConventions, scanConventions, } from '../../core/scanner.js';
|
|
20
|
+
import { analyzeRecording, findVisualCaptureCandidates, } from '../../core/recording-intelligence.js';
|
|
21
|
+
import { analyzeMocks } from '../../core/mock-intelligence.js';
|
|
22
|
+
import { generateTestFromGroups, emitQuerySummary } from '../../core/generator.js';
|
|
23
|
+
function deriveOutputPath(inputPath) {
|
|
24
|
+
const dir = dirname(inputPath);
|
|
25
|
+
const name = basename(inputPath, '.js').replace(/\.(json)$/, '');
|
|
26
|
+
return join(dir, `${name}.test.tsx`);
|
|
27
|
+
}
|
|
28
|
+
function logScore(scoreResult) {
|
|
29
|
+
console.log(pc.dim('[taro]') +
|
|
30
|
+
` Score: ${scoreResult.total}/100 (${scoreResult.grade}) — ` +
|
|
31
|
+
`query: ${scoreResult.dimensions.queryQuality}, ` +
|
|
32
|
+
`assertions: ${scoreResult.dimensions.assertionSpecificity}, ` +
|
|
33
|
+
`structure: ${scoreResult.dimensions.testStructure}`);
|
|
34
|
+
}
|
|
35
|
+
function emitScoreHints(scoreResult, queryResults = []) {
|
|
36
|
+
if (scoreResult.dimensions.queryQuality < 60) {
|
|
37
|
+
const testIdCount = queryResults.filter((queryResult) => {
|
|
38
|
+
return queryResult.method === 'getByTestId';
|
|
39
|
+
}).length;
|
|
40
|
+
console.log(pc.yellow(`[taro] Tip: ${testIdCount} getByTestId queries — consider adding aria-label`));
|
|
41
|
+
}
|
|
42
|
+
if (scoreResult.dimensions.assertionSpecificity < 60) {
|
|
43
|
+
console.log(pc.yellow('[taro] Tip: Add specific matchers like toHaveValue() for better assertions'));
|
|
44
|
+
}
|
|
45
|
+
if (scoreResult.dimensions.testStructure < 60) {
|
|
46
|
+
console.log(pc.yellow('[taro] Tip: Split into multiple it() blocks for better test organization'));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function summarizeCleanup(analyzedRecording) {
|
|
50
|
+
const { diagnostics } = analyzedRecording;
|
|
51
|
+
const parts = [];
|
|
52
|
+
if (diagnostics.removedRedundantClicks > 0) {
|
|
53
|
+
parts.push(`${diagnostics.removedRedundantClicks} redundant click(s)`);
|
|
54
|
+
}
|
|
55
|
+
if (diagnostics.removedDoubleClickNoise > 0) {
|
|
56
|
+
parts.push(`${diagnostics.removedDoubleClickNoise} dblClick noise event(s)`);
|
|
57
|
+
}
|
|
58
|
+
if (diagnostics.removedCursorWander > 0) {
|
|
59
|
+
parts.push(`${diagnostics.removedCursorWander} cursor wander step(s)`);
|
|
60
|
+
}
|
|
61
|
+
if (diagnostics.intentGroupCount > 1) {
|
|
62
|
+
parts.push(`${diagnostics.intentGroupCount} intent groups`);
|
|
63
|
+
}
|
|
64
|
+
if (parts.length === 0) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
console.log(pc.dim('[taro]') + ` Recording cleanup: ${parts.join(', ')}`);
|
|
68
|
+
}
|
|
69
|
+
function toItGroups(analyzedRecording, fallbackTitle) {
|
|
70
|
+
if (analyzedRecording.intentGroups.length > 0) {
|
|
71
|
+
return analyzedRecording.intentGroups;
|
|
72
|
+
}
|
|
73
|
+
return [
|
|
74
|
+
{
|
|
75
|
+
name: fallbackTitle || 'recorded flow',
|
|
76
|
+
steps: analyzedRecording.steps,
|
|
77
|
+
},
|
|
78
|
+
];
|
|
79
|
+
}
|
|
80
|
+
function summarizeVisualState(visualState) {
|
|
81
|
+
if (!visualState) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const parts = [visualState.reason];
|
|
85
|
+
if (visualState.dialog?.title) {
|
|
86
|
+
parts.push(`dialog=${visualState.dialog.title}`);
|
|
87
|
+
}
|
|
88
|
+
if (visualState.screenshotPath) {
|
|
89
|
+
parts.push(`screenshot=${visualState.screenshotPath}`);
|
|
90
|
+
}
|
|
91
|
+
console.log(pc.dim('[taro]') + ` Visual state: ${parts.join(', ')}`);
|
|
92
|
+
}
|
|
93
|
+
function summarizeMockAnalysis(mockAnalysis) {
|
|
94
|
+
if (!mockAnalysis) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const parts = [];
|
|
98
|
+
if (mockAnalysis.repeatedTargets.length > 0) {
|
|
99
|
+
parts.push(`${mockAnalysis.repeatedTargets.length} repeated target(s)`);
|
|
100
|
+
}
|
|
101
|
+
if (mockAnalysis.mutationLifecycles.length > 0) {
|
|
102
|
+
parts.push(`${mockAnalysis.mutationLifecycles.length} mutation flow(s)`);
|
|
103
|
+
}
|
|
104
|
+
if (mockAnalysis.instabilityWarnings.length > 0) {
|
|
105
|
+
parts.push(`${mockAnalysis.instabilityWarnings.length} stability warning(s)`);
|
|
106
|
+
}
|
|
107
|
+
if (parts.length === 0) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
console.log(pc.dim('[taro]') + ` Mock analysis: ${parts.join(', ')}`);
|
|
111
|
+
const topRecommendation = mockAnalysis.recommendations[0];
|
|
112
|
+
if (topRecommendation) {
|
|
113
|
+
console.log(pc.dim('[taro]') +
|
|
114
|
+
` Mock hint: ${topRecommendation.kind} ${topRecommendation.target} (${topRecommendation.count} file(s))`);
|
|
115
|
+
}
|
|
116
|
+
const topLifecycle = mockAnalysis.mutationLifecycles[0];
|
|
117
|
+
if (topLifecycle) {
|
|
118
|
+
console.log(pc.dim('[taro]') +
|
|
119
|
+
` Mutation lifecycle: ${topLifecycle.stages.join(' -> ')} in ${topLifecycle.file}`);
|
|
120
|
+
}
|
|
121
|
+
const topWarning = mockAnalysis.instabilityWarnings[0];
|
|
122
|
+
if (topWarning) {
|
|
123
|
+
console.warn(pc.yellow(`[taro] Mock stability: ${topWarning.reason} (${topWarning.file})`));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function findRecordingUrl(analyzedRecording) {
|
|
127
|
+
return analyzedRecording.steps.find((step) => step.action === 'navigate')?.target;
|
|
128
|
+
}
|
|
129
|
+
async function maybeCaptureVisualState(params) {
|
|
130
|
+
const { analyzedRecording, projectRoot, selector, url } = params;
|
|
131
|
+
if (!url) {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
const candidates = findVisualCaptureCandidates(analyzedRecording);
|
|
135
|
+
const visualDir = join(projectRoot, '.taro', 'visual');
|
|
136
|
+
if (candidates.length > 0) {
|
|
137
|
+
await mkdir(visualDir, { recursive: true });
|
|
138
|
+
return captureVisualState(url, {
|
|
139
|
+
reason: candidates[0].reason,
|
|
140
|
+
screenshotDir: visualDir,
|
|
141
|
+
selector: candidates[0].selector,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
if (selector) {
|
|
145
|
+
await mkdir(visualDir, { recursive: true });
|
|
146
|
+
return captureVisualState(url, {
|
|
147
|
+
reason: 'ambiguous-ui',
|
|
148
|
+
screenshotDir: visualDir,
|
|
149
|
+
selector,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
async function maybeAnalyzeMocks(projectRoot) {
|
|
155
|
+
try {
|
|
156
|
+
return await analyzeMocks(projectRoot);
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
async function appendHistoryEntry(projectRoot, historyEntry) {
|
|
163
|
+
const taroDir = join(projectRoot, '.taro');
|
|
164
|
+
await mkdir(taroDir, { recursive: true });
|
|
165
|
+
const historyPath = join(taroDir, 'history.json');
|
|
166
|
+
let history = [];
|
|
167
|
+
try {
|
|
168
|
+
await access(historyPath);
|
|
169
|
+
const historyContent = await readFile(historyPath, 'utf-8');
|
|
170
|
+
history = JSON.parse(historyContent);
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
history = [];
|
|
174
|
+
}
|
|
175
|
+
history.push(historyEntry);
|
|
176
|
+
await writeFile(historyPath, JSON.stringify(history, null, 2), 'utf-8');
|
|
177
|
+
}
|
|
178
|
+
async function finalizeGeneratedOutput(params) {
|
|
179
|
+
const { code, outputPath, projectRoot, recordingFile, scoreResult } = params;
|
|
180
|
+
const verification = verifySyntax(code, outputPath);
|
|
181
|
+
if (!verification.valid) {
|
|
182
|
+
console.error(pc.red('[taro] Error: Post-write verification failed'));
|
|
183
|
+
console.error(pc.red(` ${verification.error}`));
|
|
184
|
+
console.error(pc.red(' This is a Taro bug. Please report it.'));
|
|
185
|
+
process.exit(1);
|
|
186
|
+
}
|
|
187
|
+
console.log(pc.green('[taro] ✓ post-write verified'));
|
|
188
|
+
await appendHistoryEntry(projectRoot, {
|
|
189
|
+
timestamp: new Date().toISOString(),
|
|
190
|
+
recordingFile,
|
|
191
|
+
score: scoreResult.total,
|
|
192
|
+
grade: scoreResult.grade,
|
|
193
|
+
dimensions: scoreResult.dimensions,
|
|
194
|
+
});
|
|
195
|
+
try {
|
|
196
|
+
const detectedConventions = await analyzeSingleTestFile(projectRoot, outputPath);
|
|
197
|
+
await mergeConventions(projectRoot, detectedConventions);
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
// Convention learning is best-effort, do not fail generation.
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
export function createGenerateCommand() {
|
|
204
|
+
const generate = new Command('generate');
|
|
205
|
+
generate
|
|
206
|
+
.description('Generate RTL test from Chrome Recorder export')
|
|
207
|
+
.argument('<file>', 'Path to the Chrome Recorder JSON export file')
|
|
208
|
+
.option('-o, --output <path>', 'Output file path for the generated test')
|
|
209
|
+
.option('-d, --dry-run', 'Preview the generated test without writing to disk', false)
|
|
210
|
+
.option('-f, --force', 'Overwrite existing test file', false)
|
|
211
|
+
.action(async (file, options) => {
|
|
212
|
+
const filePath = resolve(file);
|
|
213
|
+
const projectRoot = cwd();
|
|
214
|
+
// 1. Verify file is accessible
|
|
215
|
+
try {
|
|
216
|
+
await access(filePath);
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
console.error(pc.red('Error:') + ` File not found or not accessible: ${pc.bold(filePath)}`);
|
|
220
|
+
process.exit(1);
|
|
221
|
+
}
|
|
222
|
+
// 2. Read raw JSON
|
|
223
|
+
let rawContent;
|
|
224
|
+
try {
|
|
225
|
+
rawContent = await readFile(filePath, 'utf-8');
|
|
226
|
+
}
|
|
227
|
+
catch (err) {
|
|
228
|
+
console.error(pc.red('Error:') + ` Failed to read file: ${pc.bold(filePath)}\n${String(err)}`);
|
|
229
|
+
process.exit(1);
|
|
230
|
+
}
|
|
231
|
+
// Detect JS format
|
|
232
|
+
const isJsFormat = filePath.endsWith('.js') || rawContent.includes('@jest-environment-options');
|
|
233
|
+
if (isJsFormat) {
|
|
234
|
+
// Step 1: Context scan (CTX-01–05)
|
|
235
|
+
let conventions = await readConventions(projectRoot);
|
|
236
|
+
if (!conventions) {
|
|
237
|
+
console.log(pc.dim('[taro]') + ' Scanning project conventions...');
|
|
238
|
+
conventions = await scanConventions(projectRoot);
|
|
239
|
+
}
|
|
240
|
+
// Step 2: Parse JS file via Babel AST (QRY-01, TEST-01)
|
|
241
|
+
let jsResult;
|
|
242
|
+
try {
|
|
243
|
+
jsResult = await parseJsRecording(rawContent);
|
|
244
|
+
}
|
|
245
|
+
catch (err) {
|
|
246
|
+
console.error(pc.red('Error:') + ` Failed to parse JS recording: ${String(err)}`);
|
|
247
|
+
process.exit(1);
|
|
248
|
+
}
|
|
249
|
+
console.log(pc.green('Parsed:') +
|
|
250
|
+
` ${pc.bold(jsResult.title)} — ${jsResult.steps.length} steps, ${jsResult.itGroups.length} test group(s)`);
|
|
251
|
+
const analyzedRecording = analyzeRecording({
|
|
252
|
+
title: jsResult.title,
|
|
253
|
+
steps: jsResult.steps,
|
|
254
|
+
rawStepCount: jsResult.steps.length,
|
|
255
|
+
});
|
|
256
|
+
summarizeCleanup(analyzedRecording);
|
|
257
|
+
const visualState = await maybeCaptureVisualState({
|
|
258
|
+
analyzedRecording,
|
|
259
|
+
projectRoot,
|
|
260
|
+
selector: jsResult.querySelectorCalls[0]?.selector,
|
|
261
|
+
url: jsResult.environmentUrl,
|
|
262
|
+
});
|
|
263
|
+
summarizeVisualState(visualState);
|
|
264
|
+
const mockAnalysis = await maybeAnalyzeMocks(projectRoot);
|
|
265
|
+
summarizeMockAnalysis(mockAnalysis);
|
|
266
|
+
// Step 3: Resolve document.querySelector selectors via Playwright (QRY-02, QRY-03)
|
|
267
|
+
const queryResults = [];
|
|
268
|
+
if (jsResult.querySelectorCalls.length > 0 && jsResult.environmentUrl) {
|
|
269
|
+
console.log(pc.dim('[taro]') +
|
|
270
|
+
` Resolving ${jsResult.querySelectorCalls.length} selector(s) via Playwright...`);
|
|
271
|
+
const selectors = jsResult.querySelectorCalls.map((c) => c.selector);
|
|
272
|
+
const elementMap = await inspectElements(jsResult.environmentUrl, selectors);
|
|
273
|
+
for (const call of jsResult.querySelectorCalls) {
|
|
274
|
+
const info = elementMap.get(call.selector) ?? null;
|
|
275
|
+
if (!info) {
|
|
276
|
+
// App not running or element not found — emit QRY-02 warning (handled inside inspectElements)
|
|
277
|
+
// Use getByTestId fallback
|
|
278
|
+
const fallbackResult = buildQuery({ tagName: 'div', role: null, ariaLabel: null, ariaLabelledBy: null,
|
|
279
|
+
innerText: '', value: undefined, type: undefined, placeholder: null, isPresent: false }, call.selector);
|
|
280
|
+
queryResults.push({ ...fallbackResult, line: call.line });
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
const result = buildQuery(info, call.selector);
|
|
284
|
+
if (result.quality === 'fragile')
|
|
285
|
+
emitQry03Warning(call.selector);
|
|
286
|
+
const matcher = selectMatcher(info, 'assert');
|
|
287
|
+
queryResults.push({ ...result, matcher, line: call.line });
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
else if (jsResult.querySelectorCalls.length > 0 && !jsResult.environmentUrl) {
|
|
292
|
+
console.warn(pc.yellow('[taro]') +
|
|
293
|
+
' QRY-02: No @jest-environment-options URL found — cannot resolve document.querySelector selectors. Falling back to getByTestId.');
|
|
294
|
+
}
|
|
295
|
+
// Step 4: Generate test code with multi-it() blocks (TEST-01, TEST-03)
|
|
296
|
+
const outputPath = options.output ?? deriveOutputPath(filePath);
|
|
297
|
+
const generated = generateTestFromGroups(jsResult.title, toItGroups(analyzedRecording, jsResult.title), {
|
|
298
|
+
outputPath,
|
|
299
|
+
dryRun: options.dryRun,
|
|
300
|
+
conventions,
|
|
301
|
+
queryResults,
|
|
302
|
+
});
|
|
303
|
+
// Step 5: Emit query quality summary (QRY-01)
|
|
304
|
+
emitQuerySummary(queryResults);
|
|
305
|
+
// Pre-write audit: compute score before writing
|
|
306
|
+
const scoreResult = scoreGeneratedTest(generated.code, queryResults);
|
|
307
|
+
logScore(scoreResult);
|
|
308
|
+
emitScoreHints(scoreResult, queryResults);
|
|
309
|
+
// Step 6: Write or preview
|
|
310
|
+
if (options.dryRun) {
|
|
311
|
+
console.log(pc.yellow('\nDry run — test preview:\n'));
|
|
312
|
+
console.log(pc.dim('─'.repeat(60)));
|
|
313
|
+
console.log(generated.code);
|
|
314
|
+
console.log(pc.dim('─'.repeat(60)));
|
|
315
|
+
console.log(pc.dim(`\n[taro] Score: ${scoreResult.total}/100 (${scoreResult.grade})`));
|
|
316
|
+
console.log(pc.yellow(`\nWould write to: ${pc.bold(outputPath)}`));
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
try {
|
|
320
|
+
const result = await writeTestFile(generated.code, outputPath, {
|
|
321
|
+
force: options.force,
|
|
322
|
+
createDir: true,
|
|
323
|
+
});
|
|
324
|
+
await finalizeGeneratedOutput({
|
|
325
|
+
code: generated.code,
|
|
326
|
+
outputPath: result.filePath,
|
|
327
|
+
projectRoot,
|
|
328
|
+
recordingFile: filePath,
|
|
329
|
+
scoreResult,
|
|
330
|
+
});
|
|
331
|
+
const action = result.overwritten ? pc.yellow('Updated') : pc.green('Created');
|
|
332
|
+
console.log(`${action}: ${pc.bold(result.filePath)}`);
|
|
333
|
+
}
|
|
334
|
+
catch (err) {
|
|
335
|
+
console.error(pc.red('Error:') + ` ${String(err)}`);
|
|
336
|
+
process.exit(1);
|
|
337
|
+
}
|
|
338
|
+
return; // Exit action for JS path — do not fall through to JSON pipeline
|
|
339
|
+
}
|
|
340
|
+
// 3. Parse JSON
|
|
341
|
+
let parsedJson;
|
|
342
|
+
try {
|
|
343
|
+
parsedJson = JSON.parse(rawContent);
|
|
344
|
+
}
|
|
345
|
+
catch {
|
|
346
|
+
console.error(pc.red('Error:') +
|
|
347
|
+
` Invalid JSON in file: ${pc.bold(filePath)}\nEnsure the file is a valid Chrome Recorder export.`);
|
|
348
|
+
process.exit(1);
|
|
349
|
+
}
|
|
350
|
+
// 4. Validate schema
|
|
351
|
+
const validation = validateRecording(parsedJson);
|
|
352
|
+
if (!validation.valid) {
|
|
353
|
+
console.error(pc.red('Error:') +
|
|
354
|
+
` Invalid Chrome Recorder format in ${pc.bold(filePath)}\n` +
|
|
355
|
+
formatValidationErrors(validation.errors));
|
|
356
|
+
process.exit(1);
|
|
357
|
+
}
|
|
358
|
+
// 5. Normalize steps
|
|
359
|
+
let normalizedRecording;
|
|
360
|
+
try {
|
|
361
|
+
normalizedRecording = await parseRecording(filePath);
|
|
362
|
+
}
|
|
363
|
+
catch (err) {
|
|
364
|
+
console.error(pc.red('Error:') + ` Failed to parse recording: ${String(err)}`);
|
|
365
|
+
process.exit(1);
|
|
366
|
+
}
|
|
367
|
+
console.log(pc.green('Parsed:') +
|
|
368
|
+
` ${pc.bold(normalizedRecording.title)} — ${normalizedRecording.steps.length} steps`);
|
|
369
|
+
const analyzedRecording = analyzeRecording(normalizedRecording);
|
|
370
|
+
summarizeCleanup(analyzedRecording);
|
|
371
|
+
const visualState = await maybeCaptureVisualState({
|
|
372
|
+
analyzedRecording,
|
|
373
|
+
projectRoot,
|
|
374
|
+
url: findRecordingUrl(analyzedRecording),
|
|
375
|
+
});
|
|
376
|
+
summarizeVisualState(visualState);
|
|
377
|
+
const mockAnalysis = await maybeAnalyzeMocks(projectRoot);
|
|
378
|
+
summarizeMockAnalysis(mockAnalysis);
|
|
379
|
+
// 6. Generate test code
|
|
380
|
+
const outputPath = options.output ?? deriveOutputPath(filePath);
|
|
381
|
+
const generated = generateTest(analyzedRecording, { outputPath, dryRun: options.dryRun });
|
|
382
|
+
const scoreResult = scoreGeneratedTest(generated.code);
|
|
383
|
+
logScore(scoreResult);
|
|
384
|
+
emitScoreHints(scoreResult);
|
|
385
|
+
// 7. Write or preview
|
|
386
|
+
if (options.dryRun) {
|
|
387
|
+
console.log(pc.yellow('\nDry run — test preview:\n'));
|
|
388
|
+
console.log(pc.dim('─'.repeat(60)));
|
|
389
|
+
console.log(generated.code);
|
|
390
|
+
console.log(pc.dim('─'.repeat(60)));
|
|
391
|
+
console.log(pc.dim(`\n[taro] Score: ${scoreResult.total}/100 (${scoreResult.grade})`));
|
|
392
|
+
console.log(pc.yellow(`\nWould write to: ${pc.bold(outputPath)}`));
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
try {
|
|
396
|
+
const result = await writeTestFile(generated.code, outputPath, {
|
|
397
|
+
force: options.force,
|
|
398
|
+
createDir: true,
|
|
399
|
+
});
|
|
400
|
+
await finalizeGeneratedOutput({
|
|
401
|
+
code: generated.code,
|
|
402
|
+
outputPath: result.filePath,
|
|
403
|
+
projectRoot,
|
|
404
|
+
recordingFile: filePath,
|
|
405
|
+
scoreResult,
|
|
406
|
+
});
|
|
407
|
+
const action = result.overwritten ? pc.yellow('Updated') : pc.green('Created');
|
|
408
|
+
console.log(`${action}: ${pc.bold(result.filePath)}`);
|
|
409
|
+
}
|
|
410
|
+
catch (err) {
|
|
411
|
+
console.error(pc.red('Error:') + ` ${String(err)}`);
|
|
412
|
+
process.exit(1);
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
return generate;
|
|
416
|
+
}
|
|
417
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/cli/commands/generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RTL test code generation
|
|
3
|
+
* Converts NormalizedRecording into valid React Testing Library test code.
|
|
4
|
+
*
|
|
5
|
+
* Query priority (accessibility-first):
|
|
6
|
+
* getByRole > getByLabelText > getByText > getByPlaceholderText > getByTestId
|
|
7
|
+
*/
|
|
8
|
+
import type { NormalizedRecording, QueryResult, ItGroup } from '../types/recording.js';
|
|
9
|
+
import type { ConventionsSchema } from '../types/conventions.js';
|
|
10
|
+
export interface GeneratorOptions {
|
|
11
|
+
outputPath?: string;
|
|
12
|
+
dryRun?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface GeneratedTest {
|
|
15
|
+
code: string;
|
|
16
|
+
testName: string;
|
|
17
|
+
filePath?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function generateTest(recording: NormalizedRecording, options?: GeneratorOptions): GeneratedTest;
|
|
20
|
+
export interface GeneratedTestV3 extends GeneratedTest {
|
|
21
|
+
queryResults?: QueryResult[];
|
|
22
|
+
itGroupCount?: number;
|
|
23
|
+
}
|
|
24
|
+
export declare function emitQuerySummary(queryResults: QueryResult[]): void;
|
|
25
|
+
export interface GenerateFromGroupsOptions {
|
|
26
|
+
outputPath?: string;
|
|
27
|
+
dryRun?: boolean;
|
|
28
|
+
conventions?: ConventionsSchema;
|
|
29
|
+
queryResults?: QueryResult[];
|
|
30
|
+
}
|
|
31
|
+
export declare function generateTestFromGroups(title: string, itGroups: ItGroup[], options?: GenerateFromGroupsOptions): GeneratedTestV3;
|
|
32
|
+
//# sourceMappingURL=generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/core/generator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAkB,WAAW,EAAE,OAAO,EAAgB,MAAM,uBAAuB,CAAA;AACpH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAShE,MAAM,WAAW,gBAAgB;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAmGD,wBAAgB,YAAY,CAC1B,SAAS,EAAE,mBAAmB,EAC9B,OAAO,GAAE,gBAAqB,GAC7B,aAAa,CAkBf;AAID,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACpD,YAAY,CAAC,EAAE,WAAW,EAAE,CAAA;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,WAAW,EAAE,GAAG,IAAI,CAgClE;AAED,MAAM,WAAW,yBAAyB;IACxC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,WAAW,CAAC,EAAE,iBAAiB,CAAA;IAC/B,YAAY,CAAC,EAAE,WAAW,EAAE,CAAA;CAC7B;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,GAAE,yBAA8B,GACtC,eAAe,CA4CjB"}
|