@skyramp/mcp
Version:
Skyramp MCP (Model Context Protocol) Server - AI-powered test generation and execution
160 lines (141 loc) • 6.33 kB
JavaScript
/**
* Build optimized drift analysis prompt - compares TEST expectations vs CURRENT CODE
*/
export function buildDriftAnalysisPrompt(testType, testFile, fileChanges, apiSchemaChanges, uiComponentChanges) {
const isUiTest = testType === "ui" || testType === "e2e";
return `# Test Drift Analysis
You are analyzing drift for a **${testType.toUpperCase()}** test to find breaking changes.
## Test File
${testFile}
## Changed Files (${fileChanges.length})
${fileChanges.length > 0
? fileChanges
.map((c) => `- ${c.file} (+${c.linesAdded}/-${c.linesRemoved})`)
.join("\n")
: "No changes detected"}
${buildSchemaChangesSection(apiSchemaChanges, uiComponentChanges)}
## Your Task
${isUiTest ? buildUiAnalysisInstructions() : buildApiAnalysisInstructions()}
## Scoring Guide
- **85-100**: Critical breaking changes (type mismatch, missing endpoint/selector, auth change)
- **60-84**: High impact (path changed, required field added, status code change)
- **40-59**: Medium impact (optional field removed, component renamed)
- **20-39**: Low impact (new optional fields, minor refactoring)
- **0-19**: Minimal/no impact
## Output Format (JSON)
\`\`\`json
{
"driftScore": 0-100,
"reasoning": "Concise explanation of key mismatches",
"breakingChanges": ["specific mismatch 1", "specific mismatch 2"],
"apiDependencyChanges": [{"file": "", "linesAdded": 0, "linesRemoved": 0, "updates": ""}],
"uiDependencyChanges": [{"file": "", "linesAdded": 0, "linesRemoved": 0, "updates": ""}],
"fieldTypeChanges": [{"file": "", "field": "", "testExpects": "", "codeHas": ""}],
"endpointChanges": [{"type": "removed|modified", "path": "", "method": "", "issue": ""}],
"selectorChanges": [{"file": "", "testExpects": "", "codeHas": ""}]
}
\`\`\``;
}
function buildSchemaChangesSection(apiSchemaChanges, uiComponentChanges) {
let section = "";
if (apiSchemaChanges) {
const removed = apiSchemaChanges.endpointsRemoved;
const modified = apiSchemaChanges.endpointsModified;
const authChanged = apiSchemaChanges.authenticationChanged;
if (removed.length > 0 || modified.length > 0 || authChanged) {
section += "\n## API Schema Changes\n";
if (removed.length > 0) {
section += `- **Removed**: ${removed
.map((e) => `${e.method} ${e.path}`)
.join(", ")}\n`;
}
if (modified.length > 0) {
section += `- **Modified**: ${modified
.map((e) => `${e.method} ${e.path}`)
.join(", ")}\n`;
}
if (authChanged) {
section += "- **Authentication**: Changed\n";
}
}
}
if (uiComponentChanges) {
const hasChanges = uiComponentChanges.componentFiles.length > 0 ||
uiComponentChanges.routeFiles.length > 0 ||
uiComponentChanges.hasSelectorsChanges ||
uiComponentChanges.hasStylingChanges;
if (hasChanges) {
section += "\n## UI Component Changes\n";
if (uiComponentChanges.componentFiles.length > 0) {
section += `- **Components**: ${uiComponentChanges.componentFiles.length} files\n`;
}
if (uiComponentChanges.routeFiles.length > 0) {
section += `- **Routes**: ${uiComponentChanges.routeFiles.length} files\n`;
}
if (uiComponentChanges.hasSelectorsChanges) {
section += "- **Selectors**: Likely changed\n";
}
if (uiComponentChanges.hasStylingChanges) {
section += "- **Styles**: Changed\n";
}
}
}
return section;
}
function buildUiAnalysisInstructions() {
return `### Analysis Steps
1. **Extract Test Selectors**
- Find: \`getByTestId()\`, \`querySelector()\`, \`getElementById()\`, \`getByRole()\`
- Record: selector type and exact value
2. **Analyze Git Diffs**
- Look for changes in: \`data-testid\`, \`className\`, \`id\`, \`role\`
- Check: Lines with "-" (removed) vs "+" (added)
- Pattern: \`- data-testid="old-value"\` → \`+ data-testid="new-value"\`
3. **Compare & Detect Breaks**
- ❌ **CRITICAL**: Test selector not found in current code
- ❌ **CRITICAL**: Selector value changed (\`submit-button\` → \`submit-btn\`)
- ❌ **CRITICAL**: Element type changed (\`<button>\` → \`<div>\`)
- ❌ **HIGH**: Route changed (\`/products\` → \`/items\`)
- ❌ **HIGH**: Component renamed/removed
4. **Categorize Changes**
- **uiDependencyChanges**: Components, pages, templates (.tsx, .jsx, .vue)
- **apiDependencyChanges**: API calls, services (if E2E test)
### Key Patterns
- Selector mismatch → Score 85+
- Route change → Score 75+
- Styling only → Score 20-39`;
}
function buildApiAnalysisInstructions() {
return `### Analysis Steps
1. **Extract Test Request Data**
- Find: Request bodies, payloads, field names
- Infer types from values:
* \`"text"\` = string
* \`123\` = integer
* \`12.5\` = decimal/float
* \`true\`/\`false\` = boolean
* \`[]\` = array
* \`null\` = optional
2. **Analyze Git Diffs**
- Look for field type changes: \`- field: type_A\` → \`+ field: type_B\`
- Look for endpoint changes: \`- @app.post("/old")\` → \`+ @app.post("/new")\`
- Look for auth changes: \`- def endpoint()\` → \`+ @require_auth def endpoint()\`
- Check status codes: \`- return 200\` → \`+ return 201\`
3. **Compare & Detect Breaks**
- ❌ **CRITICAL**: Field type changed (\`int\` → \`string\`)
- ❌ **CRITICAL**: Test value type ≠ code field type
- ❌ **CRITICAL**: Endpoint removed or path changed
- ❌ **HIGH**: Required field added (test doesn't send it)
- ❌ **HIGH**: Auth added/removed
- ❌ **HIGH**: Status code changed
- ⚠️ **MEDIUM**: Response field removed (test expects it)
4. **Categorize Changes**
- **apiDependencyChanges**: Routes, controllers, models, schemas
- **uiDependencyChanges**: Only if E2E test with UI components
### Key Patterns
- Type mismatch in diff → Score 85+
- Endpoint removed → Score 85+
- Auth change → Score 75+
- New required field → Score 75+
- Response structure change → Score 60-74`;
}