@skyramp/mcp 0.0.40 → 0.0.41
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/build/prompts/code-reuse.js +20 -20
- package/build/prompts/modularization/integration-test-modularization.js +12 -10
- package/build/prompts/modularization/ui-test-modularization.js +21 -17
- package/build/services/TestGenerationService.js +2 -2
- package/build/tools/executeSkyrampTestTool.js +1 -1
- package/build/tools/trace/startTraceCollectionTool.js +11 -0
- package/package.json +2 -2
|
@@ -36,7 +36,7 @@ export function getCodeReusePrompt(testFile, language) {
|
|
|
36
36
|
- Example: Multiple sequences of \`await page.fill()\`, \`await page.click()\` directly in test body
|
|
37
37
|
- These patterns should NOT be extracted during code reuse - that's what modularization is for
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
** CODE REUSE ≠ REFACTORING**
|
|
40
40
|
- Code reuse = Finding EXISTING helper functions and reusing them
|
|
41
41
|
- Refactoring = Creating NEW helper functions from patterns (handled by modularization tool)
|
|
42
42
|
|
|
@@ -64,40 +64,40 @@ Use the Grep tool to search for other test files containing "${SKYRAMP_UTILS_HEA
|
|
|
64
64
|
- Output mode: "files_with_matches"
|
|
65
65
|
**CRITICAL: Exclude ${testFile} from the results** - only look at OTHER test files, not the current file.
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
**STOP HERE IF NO OTHER TEST FILES FOUND**
|
|
68
68
|
**IF NO OTHER TEST FILES ARE FOUND, SKIP TO STEP 6 - DO NOT CREATE ANY UTILS FILES.**
|
|
69
69
|
|
|
70
70
|
If other test files are found, read those files and look for ALREADY DEFINED helper functions with clear function signatures.
|
|
71
71
|
|
|
72
72
|
**How to identify helper functions in other test files:**
|
|
73
|
-
|
|
73
|
+
HELPER FUNCTION (move to utils):
|
|
74
74
|
- Has function signature: \`async function doSomething(params) { ... }\`
|
|
75
75
|
- Can be called multiple times with different parameters
|
|
76
76
|
- Example: \`async function fillProductForm(page, product) { ... }\`
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
NOT A HELPER FUNCTION (do not extract):
|
|
79
79
|
- Just repetitive inline test code in test body
|
|
80
80
|
- No function definition/signature
|
|
81
81
|
- Example: Multiple \`await page.getByTestId("xyz").click()\` directly in test
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
**IF OTHER TEST FILES ONLY CONTAIN REPETITIVE PATTERNS (NO ACTUAL HELPER FUNCTIONS), SKIP TO STEP 6**
|
|
84
|
+
**IF OTHER TEST FILES ARE ESSENTIALLY IDENTICAL TO CURRENT FILE, SKIP TO STEP 6**
|
|
85
85
|
|
|
86
86
|
## STEP 5: IF LOCAL HELPERS ARE FOUND IN STEP 4 THAT CAN BE REUSED in ${testFile}, MOVE THOSE LOCAL HELPERS TO UTILS SOURCE FILES AND USE THEM
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
-
|
|
90
|
-
-
|
|
91
|
-
-
|
|
92
|
-
-
|
|
88
|
+
**ONLY PROCEED WITH STEP 5 IF ALL CONDITIONS ARE MET:**
|
|
89
|
+
- You found OTHER test files in STEP 4 (not just ${testFile})
|
|
90
|
+
- Those test files contain ACTUAL HELPER FUNCTIONS with function signatures (not just repetitive patterns)
|
|
91
|
+
- The helper functions are ALREADY IMPLEMENTED and working in those OTHER test files
|
|
92
|
+
- The helper functions are DIFFERENT from the current file (not just identical patterns)
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
**IF ANY CONDITION IS NOT MET, SKIP TO STEP 6 - DO NOT CREATE ANY UTILS FILES.**
|
|
95
95
|
|
|
96
96
|
**Examples of when to SKIP STEP 5:**
|
|
97
|
-
-
|
|
98
|
-
-
|
|
99
|
-
-
|
|
100
|
-
-
|
|
97
|
+
- Other test files have identical repetitive code but no helper functions
|
|
98
|
+
- Other test files are generated from same template and look identical
|
|
99
|
+
- You see patterns but no actual function definitions
|
|
100
|
+
- You would need to CREATE new functions to extract the patterns
|
|
101
101
|
|
|
102
102
|
**CRITICAL:** For helpers found in STEP 4:
|
|
103
103
|
1. **CREATE** \`${fileName}\` file if it doesn't exist with the following header:
|
|
@@ -111,8 +111,8 @@ If other test files are found, read those files and look for ALREADY DEFINED hel
|
|
|
111
111
|
5. **IMPORT** those local helper functions from \`${fileName}\` into ${testFile}
|
|
112
112
|
6. **REPLACE** duplicate code in ${testFile} with calls to imported helper functions WITHOUT MAKING ANY OTHER CHANGE.
|
|
113
113
|
|
|
114
|
-
|
|
115
|
-
|
|
114
|
+
**CRITICAL: DO NOT CREATE UNNECESSARY HELPER FUNCTIONS**
|
|
115
|
+
**DO NOT CREATE HELPERS BASED ON PATTERNS IN THE CURRENT FILE**
|
|
116
116
|
|
|
117
117
|
## STEP 6: VERIFY AND VALIDATE
|
|
118
118
|
1. **BEFORE** making any changes, read the original test file and identify ALL helper functions
|
|
@@ -126,8 +126,8 @@ If other test files are found, read those files and look for ALREADY DEFINED hel
|
|
|
126
126
|
9. **NEVER** refactor, reorganize, or restructure existing source test files beyond moving helpers
|
|
127
127
|
10. **RUN TESTS** to ensure functionality is preserved after refactoring
|
|
128
128
|
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
**FINAL REMINDER: DO NOT CREATE HELPER FUNCTIONS FROM SCRATCH**
|
|
130
|
+
**ONLY MOVE EXISTING HELPERS FROM OTHER TEST FILES**
|
|
131
131
|
|
|
132
132
|
**IMPORTANT NOTES:**
|
|
133
133
|
- The process is designed to REUSE existing helper functions, not create new ones
|
|
@@ -29,10 +29,11 @@ Look for API calls that repeat 2+ times with IDENTICAL structure but different d
|
|
|
29
29
|
**CRITICAL RULES:**
|
|
30
30
|
1. **EXACT CODE COPY** - Copy the API call code EXACTLY as-is from the original test
|
|
31
31
|
2. **ONLY ADD PARAMETERS** - The ONLY change allowed is converting hardcoded values to parameters
|
|
32
|
-
3. **
|
|
33
|
-
4. **NO
|
|
34
|
-
5. **
|
|
35
|
-
6. **PRESERVE
|
|
32
|
+
3. **NEVER GENERALIZE SELECTORS** - Keep all selectors/locators exactly as they are in the original code (do not refactor into dynamic template strings)
|
|
33
|
+
4. **NO LOGIC CHANGES** - Do not modify conditions, validations, or assertions
|
|
34
|
+
5. **NO DATA CHANGES** - Do not change any request/response values or expected results
|
|
35
|
+
6. **PRESERVE PATH PARAMETERS** - API path parameters must be passed as function parameters
|
|
36
|
+
7. **PRESERVE ORDER** - Keep all operations in the exact same order
|
|
36
37
|
|
|
37
38
|
**PARAMETER CONVERSION RULES:**
|
|
38
39
|
- Find the values that DIFFER between repetitions (e.g., user IDs, product names)
|
|
@@ -57,12 +58,13 @@ async function getUser(userId: number) {
|
|
|
57
58
|
\`\`\`
|
|
58
59
|
|
|
59
60
|
**WHAT NOT TO DO:**
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
Generalizing or refactoring selectors into dynamic templates
|
|
62
|
+
Changing API endpoints
|
|
63
|
+
Modifying expected status codes
|
|
64
|
+
Changing request/response validation
|
|
65
|
+
Reordering operations
|
|
66
|
+
"Improving" error handling
|
|
67
|
+
Adding new assertions
|
|
66
68
|
|
|
67
69
|
## STEP 4: USE HELPERS WITH EXACT SAME DATA
|
|
68
70
|
When calling the helpers, use the EXACT same values from the original test.
|
|
@@ -20,8 +20,8 @@ Read ${filePath} completely and identify:
|
|
|
20
20
|
|
|
21
21
|
**IF CODE IS ALREADY MODULARIZED** (has functions like \`breakpoint_section_0\`, \`breakpoint_section_1\`):
|
|
22
22
|
1. **RENAME** functions with meaningful names that describe what they do
|
|
23
|
-
-
|
|
24
|
-
-
|
|
23
|
+
- BAD: \`breakpoint_section_0\`, \`breakpoint_section_1\`
|
|
24
|
+
- GOOD: \`createProduct\`, \`editProductPrice\`, \`createOrder\`
|
|
25
25
|
2. **PARAMETERIZE** hardcoded values in these functions
|
|
26
26
|
3. **DO NOT** change the function logic or structure
|
|
27
27
|
4. **DO NOT** create new functions - work with existing ones
|
|
@@ -51,11 +51,15 @@ Extract code in TWO scenarios:
|
|
|
51
51
|
|
|
52
52
|
**CRITICAL - AVOID BUGS:**
|
|
53
53
|
- Copy the code block EXACTLY as-is from the original test
|
|
54
|
+
- **NEVER generalize selectors** - Keep selectors exactly as they are in the original code
|
|
55
|
+
- CORRECT: \`await page.getByTestId("product-Product-2-price").toContainText("$444.00")\`
|
|
56
|
+
- WRONG: \`await page.getByTestId("product-\${name}-price").toContainText("$\${price}.00")\`
|
|
57
|
+
- DO NOT refactor hardcoded selectors into dynamic template strings with variables
|
|
54
58
|
- **VERIFY ALL field mappings** - EVERY \`.fill()\` must use the correct parameter
|
|
55
|
-
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
- **Replace ALL hardcoded values with parameters** - No leftover hardcoded fills
|
|
59
|
+
- CORRECT: quantity field → \`.fill(quantity.toString())\`
|
|
60
|
+
- WRONG: quantity field → \`.fill("12")\` then \`.fill(quantity.toString())\` - remove hardcoded "12"!
|
|
61
|
+
- WRONG: name field → \`.fill(description)\` - fields must match their data!
|
|
62
|
+
- **Replace ALL hardcoded values with parameters** - No leftover hardcoded fills (selectors are the ONLY exception: selectors must remain exactly as in the original code)
|
|
59
63
|
- **NEVER create new conditional logic** (no ternaries, no if/else, no loops to derive parameter values)
|
|
60
64
|
- **NEVER add logic that wasn't in the original code**
|
|
61
65
|
- Keep ALL existing logic, calculations, and assertions unchanged
|
|
@@ -63,16 +67,16 @@ Extract code in TWO scenarios:
|
|
|
63
67
|
|
|
64
68
|
**PARAMETERIZATION BEST PRACTICES:**
|
|
65
69
|
1. **Use individual parameters, not data objects** - Makes helper usage clearer
|
|
66
|
-
-
|
|
67
|
-
-
|
|
70
|
+
- GOOD: \`createProduct(page, name, price, category)\`
|
|
71
|
+
- BAD: \`createProduct(page, productData)\` - unclear what fields are needed
|
|
68
72
|
|
|
69
73
|
2. **Avoid nested helpers** - Keep helpers flat and independent
|
|
70
|
-
-
|
|
71
|
-
-
|
|
74
|
+
- GOOD: One helper does the complete operation
|
|
75
|
+
- BAD: Helper calls another helper - adds complexity
|
|
72
76
|
|
|
73
77
|
3. **No duplicate helpers** - If you have 2+ helpers doing similar things, consolidate them
|
|
74
|
-
-
|
|
75
|
-
-
|
|
78
|
+
- GOOD: One \`createOrder(email, items)\` handles both simple and complex orders
|
|
79
|
+
- BAD: \`createSimpleOrder\` and \`createOrderWithItems\` - consolidate into one
|
|
76
80
|
- Exception: Keep separate if it significantly improves readability
|
|
77
81
|
|
|
78
82
|
4. **For repetitive code**: Only parameterize values that DIFFER between occurrences
|
|
@@ -92,13 +96,13 @@ Extract code in TWO scenarios:
|
|
|
92
96
|
|
|
93
97
|
**WRONG - Bad practices:**
|
|
94
98
|
\`\`\`typescript
|
|
95
|
-
//
|
|
99
|
+
// DON'T DO THIS - Adding conditional logic to handle multiple cases
|
|
96
100
|
async function addItem(page, index: number) {
|
|
97
101
|
const name = index === 1 ? "item1" : index === 2 ? "item2" : "item3";
|
|
98
102
|
await page.fill("#name", name);
|
|
99
103
|
}
|
|
100
104
|
|
|
101
|
-
//
|
|
105
|
+
// DON'T DO THIS - Duplicate actions
|
|
102
106
|
async function createProduct(page, name) {
|
|
103
107
|
await page.click("#add-button"); // Helper clicks button
|
|
104
108
|
// ... rest of product creation
|
|
@@ -107,7 +111,7 @@ async function createProduct(page, name) {
|
|
|
107
111
|
await page.click("#add-button"); // Test ALSO clicks button - DUPLICATE!
|
|
108
112
|
await createProduct(page, "item1");
|
|
109
113
|
|
|
110
|
-
//
|
|
114
|
+
// DON'T DO THIS - Multiple helpers for same operation
|
|
111
115
|
async function createSimpleOrder(...) { }
|
|
112
116
|
async function createOrderWithItems(...) { }
|
|
113
117
|
// Should be ONE helper: createOrder(page, email, items)
|
|
@@ -115,12 +119,12 @@ async function createOrderWithItems(...) { }
|
|
|
115
119
|
|
|
116
120
|
**RIGHT - Good practices:**
|
|
117
121
|
\`\`\`typescript
|
|
118
|
-
//
|
|
122
|
+
// CORRECT - Extract with parameter, no new logic
|
|
119
123
|
async function addItem(page, name: string) {
|
|
120
124
|
await page.fill("#name", name); // Replace literal with parameter
|
|
121
125
|
}
|
|
122
126
|
|
|
123
|
-
//
|
|
127
|
+
// CORRECT - Call helper for EACH original occurrence
|
|
124
128
|
await addItem(page, "item1");
|
|
125
129
|
await addItem(page, "item2");
|
|
126
130
|
await addItem(page, "item3");
|
|
@@ -38,7 +38,7 @@ export class TestGenerationService {
|
|
|
38
38
|
if (params.codeReuse) {
|
|
39
39
|
// Only code reuse
|
|
40
40
|
postGenerationMessage += `
|
|
41
|
-
|
|
41
|
+
Test generated successfully!
|
|
42
42
|
|
|
43
43
|
⏭️**CRITICAL NEXT STEP**: Running code reuse analysis with skyramp_reuse_code tool.
|
|
44
44
|
`;
|
|
@@ -46,7 +46,7 @@ export class TestGenerationService {
|
|
|
46
46
|
else if (params.modularizeCode) {
|
|
47
47
|
// Only modularization
|
|
48
48
|
postGenerationMessage += `
|
|
49
|
-
|
|
49
|
+
Test generated successfully!
|
|
50
50
|
|
|
51
51
|
⏭️**CRITICAL NEXT STEP**: Running modularization with skyramp_modularization tool.
|
|
52
52
|
`;
|
|
@@ -5,7 +5,7 @@ import { Writable } from "stream";
|
|
|
5
5
|
import { logger } from "../utils/logger.js";
|
|
6
6
|
import { stripVTControlCharacters } from "util";
|
|
7
7
|
import fs from "fs";
|
|
8
|
-
const EXECUTOR_DOCKER_IMAGE = "skyramp/executor:v1.2.
|
|
8
|
+
const EXECUTOR_DOCKER_IMAGE = "skyramp/executor:v1.2.31";
|
|
9
9
|
const DOCKER_PLATFORM = "linux/amd64";
|
|
10
10
|
export function registerExecuteSkyrampTestTool(server) {
|
|
11
11
|
server.registerTool("skyramp_execute_test", {
|
|
@@ -88,6 +88,17 @@ For detailed documentation visit: https://www.skyramp.dev/docs/load-test/advance
|
|
|
88
88
|
};
|
|
89
89
|
try {
|
|
90
90
|
const result = await client.generateRestTest(generateOptions);
|
|
91
|
+
if (result.toLowerCase().includes("failed")) {
|
|
92
|
+
return {
|
|
93
|
+
content: [
|
|
94
|
+
{
|
|
95
|
+
type: "text",
|
|
96
|
+
text: `Trace collection failed: ${result}`,
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
isError: true,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
91
102
|
await openProxyTerminalTracked();
|
|
92
103
|
return {
|
|
93
104
|
content: [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skyramp/mcp",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.41",
|
|
4
4
|
"main": "build/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@modelcontextprotocol/sdk": "^1.11.4",
|
|
45
|
-
"@skyramp/skyramp": "^1.2.
|
|
45
|
+
"@skyramp/skyramp": "^1.2.31",
|
|
46
46
|
"@playwright/test": "^1.55.0",
|
|
47
47
|
"dockerode": "^4.0.6",
|
|
48
48
|
"zod": "^3.25.3"
|