UNPKG

@skyramp/mcp

Version:

Skyramp MCP (Model Context Protocol) Server - AI-powered test generation and execution

160 lines (141 loc) 6.33 kB
/** * 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`; }