@skyramp/mcp 0.0.30 → 0.0.32
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/index.js +10 -5
- package/build/prompts/code-reuse.js +101 -0
- package/build/prompts/fix-error-prompt.js +29 -0
- package/build/prompts/modularization/integration-test-modularization.js +92 -0
- package/build/prompts/modularization/ui-test-modularization.js +177 -0
- package/build/prompts/testGenerationPrompt.js +76 -0
- package/build/services/ModularizationService.js +26 -5
- package/build/services/ScenarioGenerationService.js +167 -0
- package/build/services/TestGenerationService.js +31 -5
- package/build/tools/__tests__/codeReuseTool.test.js +266 -0
- package/build/tools/codeReuseTool.js +45 -0
- package/build/tools/executeSkyrampTestTool.js +1 -1
- package/build/tools/fixErrorTool.js +1 -1
- package/build/tools/generateContractRestTool.js +2 -2
- package/build/tools/generateE2ERestTool.js +3 -2
- package/build/tools/generateFuzzRestTool.js +2 -2
- package/build/tools/generateIntegrationRestTool.js +7 -2
- package/build/tools/generateLoadRestTool.js +2 -2
- package/build/tools/generateScenarioRestTool.js +81 -0
- package/build/tools/generateSmokeRestTool.js +2 -2
- package/build/tools/generateUIRestTool.js +3 -2
- package/build/tools/modularizationTool.js +12 -5
- package/build/tools/startTraceCollectionTool.js +4 -4
- package/build/tools/stopTraceCollectionTool.js +11 -5
- package/build/types/TestTypes.js +20 -0
- package/build/utils/utils.js +19 -0
- package/build/utils/utils.test.js +34 -1
- package/package.json +2 -2
- package/build/prompts/modularization-prompts.js +0 -281
package/build/index.js
CHANGED
|
@@ -18,15 +18,18 @@ import { registerLoginTool } from "./tools/loginTool.js";
|
|
|
18
18
|
import { registerLogoutTool } from "./tools/logoutTool.js";
|
|
19
19
|
import { registerFixErrorTool } from "./tools/fixErrorTool.js";
|
|
20
20
|
import { registerModularizationTool } from "./tools/modularizationTool.js";
|
|
21
|
+
import { registerCodeReuseTool } from "./tools/codeReuseTool.js";
|
|
22
|
+
import { registerScenarioTestTool } from "./tools/generateScenarioRestTool.js";
|
|
21
23
|
const server = new McpServer({
|
|
22
24
|
name: "Skyramp MCP Server",
|
|
23
25
|
version: "1.0.0",
|
|
24
26
|
capabilities: {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
tools: {
|
|
28
|
+
listChanged: true,
|
|
29
|
+
},
|
|
30
|
+
prompts: {
|
|
31
|
+
listChanged: true,
|
|
32
|
+
},
|
|
30
33
|
},
|
|
31
34
|
});
|
|
32
35
|
// Register prompts
|
|
@@ -42,9 +45,11 @@ registerLoadTestTool(server);
|
|
|
42
45
|
registerIntegrationTestTool(server);
|
|
43
46
|
registerE2ETestTool(server);
|
|
44
47
|
registerUITestTool(server);
|
|
48
|
+
registerScenarioTestTool(server);
|
|
45
49
|
// Register modularization and fix error tools
|
|
46
50
|
registerModularizationTool(server);
|
|
47
51
|
registerFixErrorTool(server);
|
|
52
|
+
registerCodeReuseTool(server);
|
|
48
53
|
// Register other Skyramp tools
|
|
49
54
|
registerLoginTool(server);
|
|
50
55
|
registerLogoutTool(server);
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { generateSkyrampHeader, SKYRAMP_UTILS_HEADER } from "../utils/utils.js";
|
|
2
|
+
const LANGUAGE_EXTENSION_MAP = {
|
|
3
|
+
python: "py",
|
|
4
|
+
java: "java",
|
|
5
|
+
javascript: "js",
|
|
6
|
+
typescript: "ts",
|
|
7
|
+
};
|
|
8
|
+
export function getCodeReusePrompt(testFile, language, modularizeCode) {
|
|
9
|
+
const ext = LANGUAGE_EXTENSION_MAP[language] || "ts";
|
|
10
|
+
return `# CODE REUSE - 6 CLEAR STEPS
|
|
11
|
+
|
|
12
|
+
## STEP 1: READ TEST FILE
|
|
13
|
+
Read ${testFile} and identify what helper functions it needs.
|
|
14
|
+
|
|
15
|
+
## STEP 2: FIND EXISTING UTILS
|
|
16
|
+
Use the Grep tool to search for files containing "${SKYRAMP_UTILS_HEADER}":
|
|
17
|
+
- Pattern: "${SKYRAMP_UTILS_HEADER}"
|
|
18
|
+
- Type: "${ext}"
|
|
19
|
+
- Output mode: "files_with_matches"
|
|
20
|
+
|
|
21
|
+
**CRITICAL: Only look for util files with header ${SKYRAMP_UTILS_HEADER}** - exclude test files (files with "test", "spec", ".test.", ".spec." in the name).
|
|
22
|
+
|
|
23
|
+
Then read the matching non-test files and check if any helpers can be reused in ${testFile}.
|
|
24
|
+
|
|
25
|
+
## STEP 3: USE EXISTING HELPERS FROM UTILS SOURCE FILES
|
|
26
|
+
If helpers exist in util files:
|
|
27
|
+
- Import them into ${testFile}
|
|
28
|
+
- Remove any duplicate code in ${testFile}
|
|
29
|
+
- Test that ${testFile} still works without any errors and logical is same as original test file.
|
|
30
|
+
|
|
31
|
+
## STEP 4: FIND LOCAL HELPERS IN OTHER TEST SOURCE FILES THAT HAS HEADER ${SKYRAMP_UTILS_HEADER}
|
|
32
|
+
Use the Grep tool to search for other test files containing "${SKYRAMP_UTILS_HEADER}":
|
|
33
|
+
- Pattern: "${SKYRAMP_UTILS_HEADER}"
|
|
34
|
+
- Type: "${ext}"
|
|
35
|
+
- Output mode: "files_with_matches"
|
|
36
|
+
|
|
37
|
+
**CRITICAL: Exclude ${testFile} from the results** - only look at OTHER test files, not the current file.
|
|
38
|
+
|
|
39
|
+
**IF NO OTHER TEST FILES ARE FOUND, SKIP TO STEP 6 - DO NOT CREATE ANY UTILS FILES.**
|
|
40
|
+
|
|
41
|
+
If other test files are found, read those files and identify helper functions that can be reused in ${testFile}.
|
|
42
|
+
Look for patterns like: Form filling utilities, Navigation helpers, Authentication helpers, Data validation functions.
|
|
43
|
+
|
|
44
|
+
## 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
|
|
45
|
+
**ONLY PROCEED WITH STEP 5 IF:**
|
|
46
|
+
- You found OTHER test files in STEP 4 (not just ${testFile})
|
|
47
|
+
- Those test files contain helper functions that can be reused in ${testFile}
|
|
48
|
+
|
|
49
|
+
**IF NO REUSABLE HELPERS WERE FOUND, SKIP TO STEP 6 - DO NOT CREATE ANY UTILS FILES.**
|
|
50
|
+
|
|
51
|
+
**CRITICAL:** For helpers found in STEP 4:
|
|
52
|
+
1. **CREATE** \`skyramp_utils.${ext}\` file if it doesn't exist with the following header:
|
|
53
|
+
\`\`\`${ext}
|
|
54
|
+
${generateSkyrampHeader(language)}
|
|
55
|
+
\`\`\`
|
|
56
|
+
2. **COPY** those local helper functions from original test source files to \`utils.${ext}\` without modifying them
|
|
57
|
+
3. **DELETE** those local helper functions from test source files (REMOVE THEM COMPLETELY) WITHOUT ANY OTHER CHANGES.
|
|
58
|
+
4. **IMPORT** those local helper functions from \`utils.${ext}\` back into test source files WITHOUT MAKING ANY OTHER CHANGE.
|
|
59
|
+
5. **IMPORT** those local helper functions from \`utils.${ext}\` into ${testFile}
|
|
60
|
+
6. **REPLACE** duplicate code in ${testFile} with calls to imported helper functions WITHOUT MAKING ANY OTHER CHANGE.
|
|
61
|
+
|
|
62
|
+
**CRITICAL: DO NOT CREATE UNNECESSARY HELPER FUNCTIONS**
|
|
63
|
+
- **ONLY** extract functions that are actually duplicated and used in multiple places
|
|
64
|
+
- **DO NOT** create granular helper functions that duplicate functionality already covered by existing helpers
|
|
65
|
+
- **DO NOT** create functions that break down existing functionality into smaller pieces just for modularity
|
|
66
|
+
- **ONLY** create helpers that eliminate actual code duplication, not just for the sake of modularity
|
|
67
|
+
- **VERIFY** that each helper function serves a clear purpose and is actually used in the refactored code
|
|
68
|
+
|
|
69
|
+
**CRITICAL: EXPLICIT RULES FOR SOURCE TEST FILES:**
|
|
70
|
+
- **ONLY** remove the helper function definitions (the actual function code) that are needed for ${testFile}
|
|
71
|
+
- **ONLY** add import statements for the helper functions
|
|
72
|
+
- **DO NOT** change any other code in the source test files
|
|
73
|
+
- **DO NOT** change the test logic, test steps, or test flow
|
|
74
|
+
- **DO NOT** add new helper functions that weren't in the original file
|
|
75
|
+
- **DO NOT** modify existing function calls or test assertions
|
|
76
|
+
- **DO NOT** change variable names, test data, or test structure
|
|
77
|
+
|
|
78
|
+
## STEP 6: VERIFY AND VALIDATE
|
|
79
|
+
1. **BEFORE** making any changes, read the original test file and identify ALL helper functions
|
|
80
|
+
2. **AFTER** copying helpers to utils, read the original file again to confirm helpers are GONE
|
|
81
|
+
3. **VERIFY** that helper functions are NO LONGER in original test files
|
|
82
|
+
4. **VERIFY** that the original test files only have import statements and no duplicate code
|
|
83
|
+
5. **VERIFY** that both original and new test files import from utils and use the helper functions
|
|
84
|
+
6. **VERIFY** that no unnecessary helper functions were created (functions that duplicate existing functionality)
|
|
85
|
+
7. **VERIFY** that all helper functions in utils are actually imported and used in the test files
|
|
86
|
+
8. **REMOVE** any helper functions that are not being used after refactoring
|
|
87
|
+
9. **NEVER** refactor, reorganize, or restructure existing source test files beyond moving helpers
|
|
88
|
+
10. **RUN TESTS** to ensure functionality is preserved after refactoring
|
|
89
|
+
|
|
90
|
+
**WORKFLOW SUMMARY:**
|
|
91
|
+
1. Check existing utils with header ${SKYRAMP_UTILS_HEADER} → reuse if found WITHOUT ANY OTHER CHANGES
|
|
92
|
+
2. Search OTHER test files (not ${testFile}) for local helpers with header ${SKYRAMP_UTILS_HEADER}
|
|
93
|
+
3. **ONLY IF** reusable helpers are found in OTHER test files → move to utils and update imports
|
|
94
|
+
4. **IF NO** existing utils or reusable helpers are found in test files then reuse is complete, without creating any files or changes to the test files
|
|
95
|
+
5. Verify no duplicate code remains and tests work as expected${modularizeCode
|
|
96
|
+
? "\n6. **IMPORTANT**: After code reuse is complete, proceed to modularization by calling skyramp_modularization tool"
|
|
97
|
+
: ""}
|
|
98
|
+
|
|
99
|
+
SUMMARY: THE LLM SHOULD SUMMARIZE THE CODE REUSE PROCESS AND THE RESULTS.
|
|
100
|
+
`;
|
|
101
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export function getFixErrorsPrompt() {
|
|
2
|
+
return `
|
|
3
|
+
**Fix errors in refactored code.**
|
|
4
|
+
|
|
5
|
+
1. **Parameter Passing:** Identify functions using variables from outside scope (like 'page' object). Pass these as parameters.
|
|
6
|
+
2. **Validate Correctness:** Ensure code is free of reference errors, undefined variables, runtime issues.
|
|
7
|
+
3. **Import Paths:** Ensure import paths are correct and there are no circular imports.
|
|
8
|
+
4. **Import Validation:** Ensure all remaining imports are necessary and no missing imports cause reference errors.
|
|
9
|
+
5. **Unused Import Cleanup:** Verify that unused imports were properly removed without breaking functionality.
|
|
10
|
+
6. **UI State Management:** Check for UI state conflicts, modal interference, or element interaction issues.
|
|
11
|
+
7. **Sequential Operations:** Ensure UI operations don't interfere with each other when called in sequence.
|
|
12
|
+
|
|
13
|
+
**IMPORT ERROR DEBUGGING:**
|
|
14
|
+
- Check for missing imports that cause undefined reference errors
|
|
15
|
+
- Verify that import removal didn't break existing functionality
|
|
16
|
+
- Ensure all imported modules are actually available in the project
|
|
17
|
+
- Confirm that import syntax is correct for the target language
|
|
18
|
+
|
|
19
|
+
**CRITICAL CONSTRAINTS:**
|
|
20
|
+
- DO NOT CREATE/UPDATE package.json or requirements.txt or pom.xml or build.gradle file
|
|
21
|
+
- NEVER create dependency management files, even when linting errors suggest missing dependencies
|
|
22
|
+
- Focus on fixing code errors within existing files only
|
|
23
|
+
|
|
24
|
+
**KEY: Variables not defined within function scope MUST be passed as parameters.**
|
|
25
|
+
**UI KEY: Helper functions that perform UI operations must be self-contained and not leave modals/dialogs open.**
|
|
26
|
+
**IMPORT KEY: All imports must be either used in the code or properly removed.**
|
|
27
|
+
**DEPENDENCY KEY: DO NOT create package.json, requirements.txt, or any dependency files regardless of linting errors.**
|
|
28
|
+
`;
|
|
29
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
export function getModularizationPrompt(filePath) {
|
|
2
|
+
return `# INTEGRATION TEST MODULARIZATION - SIMPLE AND SAFE
|
|
3
|
+
|
|
4
|
+
**WRITE MODULARIZED CODE TO: ${filePath}**
|
|
5
|
+
|
|
6
|
+
**ABSOLUTELY FORBIDDEN:**
|
|
7
|
+
- DO NOT CREATE ANY INTERFACES, CLASSES, TYPES, OR NEW DATA STRUCTURES. USE INLINE TYPES ONLY.
|
|
8
|
+
- DO NOT CREATE/UPDATE package.json or requirements.txt or pom.xml or build.gradle file
|
|
9
|
+
- DO NOT CHANGE TEST LOGIC, DATA VALUES, ASSERTIONS, OR API CALLS
|
|
10
|
+
- DO NOT MODIFY EXPECTED RESPONSES OR STATUS CODES
|
|
11
|
+
|
|
12
|
+
## STEP 1: READ AND UNDERSTAND THE ORIGINAL TEST
|
|
13
|
+
**CRITICAL: Before making ANY changes:**
|
|
14
|
+
1. Read ${filePath} completely
|
|
15
|
+
2. Identify all API endpoints and their parameters
|
|
16
|
+
3. Identify all test data (request bodies, expected responses)
|
|
17
|
+
4. Identify all assertions and expected values
|
|
18
|
+
5. Document the test flow
|
|
19
|
+
6. **DO NOT PROCEED** until you fully understand what the test does
|
|
20
|
+
|
|
21
|
+
## STEP 2: FIND REPETITIVE CODE
|
|
22
|
+
Look for API calls that repeat 2+ times with IDENTICAL structure but different data.
|
|
23
|
+
|
|
24
|
+
## STEP 3: CREATE HELPER FUNCTIONS - EXTRACT ONLY, NO CHANGES
|
|
25
|
+
|
|
26
|
+
**GOLDEN RULE: COPY-PASTE THE ORIGINAL CODE INTO HELPERS, JUST ADD PARAMETERS AND REPLACE HARDCODED VALUES WITH PARAMETERS**
|
|
27
|
+
|
|
28
|
+
**CRITICAL RULES:**
|
|
29
|
+
1. **EXACT CODE COPY** - Copy the API call code EXACTLY as-is from the original test
|
|
30
|
+
2. **ONLY ADD PARAMETERS** - The ONLY change allowed is converting hardcoded values to parameters
|
|
31
|
+
3. **NO LOGIC CHANGES** - Do not modify conditions, validations, or assertions
|
|
32
|
+
4. **NO DATA CHANGES** - Do not change any request/response values or expected results
|
|
33
|
+
5. **PRESERVE PATH PARAMETERS** - API path parameters must be passed as function parameters
|
|
34
|
+
6. **PRESERVE ORDER** - Keep all operations in the exact same order
|
|
35
|
+
|
|
36
|
+
**PARAMETER CONVERSION RULES:**
|
|
37
|
+
- Find the values that DIFFER between repetitions (e.g., user IDs, product names)
|
|
38
|
+
- Make ONLY those differing values into parameters
|
|
39
|
+
- Keep everything else EXACTLY the same
|
|
40
|
+
|
|
41
|
+
**EXAMPLE OF CORRECT EXTRACTION:**
|
|
42
|
+
\`\`\`typescript
|
|
43
|
+
// Original repetitive code:
|
|
44
|
+
const response1 = await fetch("/api/users/1");
|
|
45
|
+
expect(response1.status).toBe(200);
|
|
46
|
+
|
|
47
|
+
const response2 = await fetch("/api/users/2");
|
|
48
|
+
expect(response2.status).toBe(200);
|
|
49
|
+
|
|
50
|
+
// Correct helper (EXACT copy + parameters):
|
|
51
|
+
async function getUser(userId: number) {
|
|
52
|
+
const response = await fetch(\`/api/users/\${userId}\`);
|
|
53
|
+
expect(response.status).toBe(200);
|
|
54
|
+
return response;
|
|
55
|
+
}
|
|
56
|
+
\`\`\`
|
|
57
|
+
|
|
58
|
+
**WHAT NOT TO DO:**
|
|
59
|
+
❌ Changing API endpoints
|
|
60
|
+
❌ Modifying expected status codes
|
|
61
|
+
❌ Changing request/response validation
|
|
62
|
+
❌ Reordering operations
|
|
63
|
+
❌ "Improving" error handling
|
|
64
|
+
❌ Adding new assertions
|
|
65
|
+
|
|
66
|
+
## STEP 4: USE HELPERS WITH EXACT SAME DATA
|
|
67
|
+
When calling the helpers, use the EXACT same values from the original test.
|
|
68
|
+
|
|
69
|
+
## STEP 5: FINAL VERIFICATION
|
|
70
|
+
|
|
71
|
+
**BEFORE WRITING ANY CODE, VERIFY:**
|
|
72
|
+
- [ ] I have read and understood the original test completely
|
|
73
|
+
- [ ] I have identified all API calls and their parameters
|
|
74
|
+
- [ ] I have documented all expected responses and assertions
|
|
75
|
+
- [ ] I understand the exact test flow and logic
|
|
76
|
+
|
|
77
|
+
**AFTER EXTRACTION, VERIFY:**
|
|
78
|
+
- [ ] Helper functions are EXACT copies of original code + parameters only
|
|
79
|
+
- [ ] NO API endpoints have been changed
|
|
80
|
+
- [ ] NO expected status codes or responses have been modified
|
|
81
|
+
- [ ] ALL test data values match the original test exactly
|
|
82
|
+
- [ ] Helper calls use the EXACT same values from the original test
|
|
83
|
+
- [ ] NO duplicate API call code remains in main test
|
|
84
|
+
|
|
85
|
+
**FINAL SANITY CHECK:**
|
|
86
|
+
Run through the modularized test mentally:
|
|
87
|
+
1. Does it make the exact same API calls?
|
|
88
|
+
2. Does it use the exact same request data?
|
|
89
|
+
3. Does it expect the exact same responses?
|
|
90
|
+
|
|
91
|
+
If ANY answer is "no", DO NOT submit - fix the modularization first.`;
|
|
92
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
export function getModularizationPrompt(filePath) {
|
|
2
|
+
return `# UI TEST MODULARIZATION - IMPROVE READABILITY AND REDUCE DUPLICATION
|
|
3
|
+
|
|
4
|
+
**WRITE MODULARIZED CODE TO: ${filePath}**
|
|
5
|
+
|
|
6
|
+
**ABSOLUTELY FORBIDDEN:**
|
|
7
|
+
- DO NOT CREATE INTERFACES, CLASSES, TYPES, OR NEW DATA STRUCTURES
|
|
8
|
+
- DO NOT CHANGE TEST LOGIC, DATA VALUES, CALCULATIONS, OR ASSERTIONS
|
|
9
|
+
- DO NOT CREATE/UPDATE package.json, requirements.txt, pom.xml, build.gradle file
|
|
10
|
+
|
|
11
|
+
## STEP 1: READ THE ORIGINAL TEST
|
|
12
|
+
Read ${filePath} completely and identify:
|
|
13
|
+
- All test data values (names, prices, quantities, totals)
|
|
14
|
+
- All calculations and expected results
|
|
15
|
+
- The exact test flow
|
|
16
|
+
- **Check if code is already modularized** (e.g., \`breakpoint_section_0\`, \`breakpoint_section_1\` functions)
|
|
17
|
+
|
|
18
|
+
## STEP 2: HANDLE PRE-MODULARIZED CODE
|
|
19
|
+
|
|
20
|
+
**IF CODE IS ALREADY MODULARIZED** (has functions like \`breakpoint_section_0\`, \`breakpoint_section_1\`):
|
|
21
|
+
1. **RENAME** functions with meaningful names that describe what they do
|
|
22
|
+
- ❌ BAD: \`breakpoint_section_0\`, \`breakpoint_section_1\`
|
|
23
|
+
- ✅ GOOD: \`createProduct\`, \`editProductPrice\`, \`createOrder\`
|
|
24
|
+
2. **PARAMETERIZE** hardcoded values in these functions
|
|
25
|
+
3. **DO NOT** change the function logic or structure
|
|
26
|
+
4. **DO NOT** create new functions - work with existing ones
|
|
27
|
+
5. **SKIP to STEP 5** for verification
|
|
28
|
+
|
|
29
|
+
**IF CODE IS NOT MODULARIZED**, proceed to STEP 3.
|
|
30
|
+
|
|
31
|
+
## STEP 3: IDENTIFY EXTRACTION OPPORTUNITIES
|
|
32
|
+
|
|
33
|
+
Extract code in TWO scenarios:
|
|
34
|
+
|
|
35
|
+
**A) REPETITIVE CODE** - Code that repeats 2+ times with IDENTICAL structure but different data
|
|
36
|
+
- Extract EACH occurrence as a separate helper call
|
|
37
|
+
- Don't try to "unify" variations with conditional logic
|
|
38
|
+
|
|
39
|
+
**B) LOGICAL SECTIONS** - Self-contained operations (5+ lines) that improve readability
|
|
40
|
+
- Examples: "create product", "fill order form", "verify result"
|
|
41
|
+
- Must be cohesive - related operations that achieve one goal
|
|
42
|
+
|
|
43
|
+
**Don't extract:**
|
|
44
|
+
- Code less than 5 lines (unless highly repetitive)
|
|
45
|
+
- Navigation sequences (\`navbar-\` clicks, \`page.goto\`)
|
|
46
|
+
- Single operations with no repetition
|
|
47
|
+
|
|
48
|
+
## STEP 3: EXTRACT INTO HELPERS
|
|
49
|
+
|
|
50
|
+
**GOLDEN RULE: Copy the original code exactly, only add parameters for values that differ**
|
|
51
|
+
|
|
52
|
+
**CRITICAL - AVOID BUGS:**
|
|
53
|
+
- Copy the code block EXACTLY as-is from the original test
|
|
54
|
+
- **VERIFY ALL field mappings** - EVERY \`.fill()\` must use the correct parameter
|
|
55
|
+
- ✅ CORRECT: quantity field → \`.fill(quantity.toString())\`
|
|
56
|
+
- ❌ WRONG: quantity field → \`.fill("12")\` then \`.fill(quantity.toString())\` - remove hardcoded "12"!
|
|
57
|
+
- ❌ WRONG: name field → \`.fill(description)\` - fields must match their data!
|
|
58
|
+
- **Replace ALL hardcoded values with parameters** - No leftover hardcoded fills
|
|
59
|
+
- **NEVER create new conditional logic** (no ternaries, no if/else, no loops to derive parameter values)
|
|
60
|
+
- **NEVER add logic that wasn't in the original code**
|
|
61
|
+
- Keep ALL existing logic, calculations, and assertions unchanged
|
|
62
|
+
- Keep ALL lines in the same order (except: remove fills with wrong/temporary hardcoded values)
|
|
63
|
+
|
|
64
|
+
**PARAMETERIZATION BEST PRACTICES:**
|
|
65
|
+
1. **Use individual parameters, not data objects** - Makes helper usage clearer
|
|
66
|
+
- ✅ GOOD: \`createProduct(page, name, price, category)\`
|
|
67
|
+
- ❌ BAD: \`createProduct(page, productData)\` - unclear what fields are needed
|
|
68
|
+
|
|
69
|
+
2. **Avoid nested helpers** - Keep helpers flat and independent
|
|
70
|
+
- ✅ GOOD: One helper does the complete operation
|
|
71
|
+
- ❌ BAD: Helper calls another helper - adds complexity
|
|
72
|
+
|
|
73
|
+
3. **No duplicate helpers** - If you have 2+ helpers doing similar things, consolidate them
|
|
74
|
+
- ✅ GOOD: One \`createOrder(email, items)\` handles both simple and complex orders
|
|
75
|
+
- ❌ BAD: \`createSimpleOrder\` and \`createOrderWithItems\` - consolidate into one
|
|
76
|
+
- Exception: Keep separate if it significantly improves readability
|
|
77
|
+
|
|
78
|
+
4. **For repetitive code**: Only parameterize values that DIFFER between occurrences
|
|
79
|
+
|
|
80
|
+
5. **NEVER compute parameters**: Pass literal values directly, don't create logic to derive them
|
|
81
|
+
|
|
82
|
+
6. **If you need conditionals to choose parameter values, extract each case separately instead**
|
|
83
|
+
|
|
84
|
+
7. **Loops in helpers**: Generally avoid, but acceptable if:
|
|
85
|
+
- The loop existed in the original code, OR
|
|
86
|
+
- It significantly improves readability without changing test behavior
|
|
87
|
+
- Example: Looping through order items is acceptable if each item is explicitly listed at call site
|
|
88
|
+
|
|
89
|
+
**NAVIGATION RULE:**
|
|
90
|
+
- Keep \`navbar-\` clicks and main \`page.goto\` in the test body
|
|
91
|
+
- Exception: Helper can include \`page.goto\` to navigate back after form submissions that redirect
|
|
92
|
+
|
|
93
|
+
**WRONG - Bad practices:**
|
|
94
|
+
\`\`\`typescript
|
|
95
|
+
// ❌ DON'T DO THIS - Adding conditional logic to handle multiple cases
|
|
96
|
+
async function addItem(page, index: number) {
|
|
97
|
+
const name = index === 1 ? "item1" : index === 2 ? "item2" : "item3";
|
|
98
|
+
await page.fill("#name", name);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// ❌ DON'T DO THIS - Duplicate actions
|
|
102
|
+
async function createProduct(page, name) {
|
|
103
|
+
await page.click("#add-button"); // Helper clicks button
|
|
104
|
+
// ... rest of product creation
|
|
105
|
+
}
|
|
106
|
+
// Then in test:
|
|
107
|
+
await page.click("#add-button"); // Test ALSO clicks button - DUPLICATE!
|
|
108
|
+
await createProduct(page, "item1");
|
|
109
|
+
|
|
110
|
+
// ❌ DON'T DO THIS - Multiple helpers for same operation
|
|
111
|
+
async function createSimpleOrder(...) { }
|
|
112
|
+
async function createOrderWithItems(...) { }
|
|
113
|
+
// Should be ONE helper: createOrder(page, email, items)
|
|
114
|
+
\`\`\`
|
|
115
|
+
|
|
116
|
+
**RIGHT - Good practices:**
|
|
117
|
+
\`\`\`typescript
|
|
118
|
+
// ✅ CORRECT - Extract with parameter, no new logic
|
|
119
|
+
async function addItem(page, name: string) {
|
|
120
|
+
await page.fill("#name", name); // Replace literal with parameter
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// ✅ CORRECT - Call helper for EACH original occurrence
|
|
124
|
+
await addItem(page, "item1");
|
|
125
|
+
await addItem(page, "item2");
|
|
126
|
+
await addItem(page, "item3");
|
|
127
|
+
|
|
128
|
+
// ✅ CORRECT - One helper handles all cases
|
|
129
|
+
async function createOrder(page, email, items) {
|
|
130
|
+
// ... setup
|
|
131
|
+
for (const item of items) { // Loop OK if items explicit at call site
|
|
132
|
+
await addItem(page, item.name, item.quantity);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Call with explicit items:
|
|
136
|
+
await createOrder(page, "test@email.com", [
|
|
137
|
+
{ name: "item1", quantity: 1 },
|
|
138
|
+
{ name: "item2", quantity: 2 }
|
|
139
|
+
]);
|
|
140
|
+
\`\`\`
|
|
141
|
+
|
|
142
|
+
## STEP 4: CALL HELPERS WITH EXACT SAME VALUES
|
|
143
|
+
Use the EXACT same values from the original test when calling helpers.
|
|
144
|
+
|
|
145
|
+
## STEP 5: VERIFY - CRITICAL CHECKS
|
|
146
|
+
|
|
147
|
+
**BUGS TO AVOID:**
|
|
148
|
+
- [ ] **ALL field mappings verified** - EVERY \`.fill()\` uses the correct parameter. Check field gets quantity parameter, NOT hardcoded
|
|
149
|
+
- [ ] **No duplicate helpers** - Consolidate similar helpers (e.g., one createOrder vs createSimpleOrder + createOrderWithItems)
|
|
150
|
+
- [ ] **No nested helpers** - Helpers don't call other helpers unnecessarily
|
|
151
|
+
- [ ] **Clear parameters** - Individual parameters (name, price) not data objects
|
|
152
|
+
- [ ] **No duplicate actions** - Don't click "Add Product" button in test AND in helper - choose one place
|
|
153
|
+
- [ ] **No new loops** - Exception: acceptable if it improves readability and items are explicit at call site
|
|
154
|
+
|
|
155
|
+
**DATA INTEGRITY:**
|
|
156
|
+
- [ ] Helpers are exact copies of original + parameters only
|
|
157
|
+
- [ ] All data values match the original test exactly
|
|
158
|
+
- [ ] All calculations produce identical results
|
|
159
|
+
- [ ] Helper calls use the same values as original
|
|
160
|
+
- [ ] No navigation code in helpers (except page.goto for state)
|
|
161
|
+
- [ ] No duplicate code in main test
|
|
162
|
+
|
|
163
|
+
**READABILITY:**
|
|
164
|
+
- [ ] Helper names clearly describe what they do
|
|
165
|
+
- [ ] Test flow is easy to follow
|
|
166
|
+
- [ ] Helper signatures are clear (individual params > data objects)
|
|
167
|
+
|
|
168
|
+
**FINAL CHECK:**
|
|
169
|
+
1. Does the modularized test perform the exact same operations?
|
|
170
|
+
2. With the exact same data?
|
|
171
|
+
3. Expecting the exact same results?
|
|
172
|
+
4. Is it MORE readable than the original?
|
|
173
|
+
|
|
174
|
+
If ANY answer is "no", fix it before submitting.
|
|
175
|
+
|
|
176
|
+
**When in doubt, don't extract - keep original code unchanged.**`;
|
|
177
|
+
}
|
|
@@ -101,13 +101,89 @@ Let us generate an E2E test with backend trace file skyramp-traces.json and fron
|
|
|
101
101
|
Let us generate a UI test with frontend playwright trace file skyramp_playwright.zip using Python language and Pytest framework.
|
|
102
102
|
\`\`\`
|
|
103
103
|
|
|
104
|
+
**SCENARIO PARSING:**
|
|
105
|
+
- Purpose: Parse natural language scenarios into structured JSON arrays of API requests
|
|
106
|
+
- Requirements: A natural language scenario description, API schema (OpenAPI/Swagger file or URL)
|
|
107
|
+
- Features: Automatically breaks down any user-provided scenario into sequential API calls with request chaining
|
|
108
|
+
- Output: Returns a JSON array where each element represents an API request with method, endpoint, parameters, and dependencies
|
|
109
|
+
|
|
110
|
+
**Usage:**
|
|
111
|
+
Describe any multi-step workflow in natural language, and the tool will parse it against your API schema to create a structured JSON array of API requests. Use this JSON output with other test generation tools.
|
|
112
|
+
|
|
104
113
|
- Default Language: Python
|
|
105
114
|
- Default Framework: Pytest
|
|
106
115
|
- Supported Languages: Python, Java, JavaScript, TypeScript
|
|
107
116
|
- Supported Frameworks: Pytest, Robot, JUnit, Playwright
|
|
108
117
|
|
|
118
|
+
**Example Scenario Parsing:**
|
|
119
|
+
Prompt:
|
|
120
|
+
Generate scenario for Skyramp Demo Shop API whose schema is https://demoshop.skyramp.dev/openapi.json
|
|
121
|
+
1. create a new product called Skyramp Tester which costs $999, for the other fields chose reasonable values
|
|
122
|
+
2. then create an order with 1x Skyramp Tester
|
|
123
|
+
|
|
124
|
+
Trace File:
|
|
125
|
+
[
|
|
126
|
+
{
|
|
127
|
+
"Source": "172.20.0.1:56948",
|
|
128
|
+
"Destination": "demoshop.skyramp.dev",
|
|
129
|
+
"RequestBody": "{\"name\":\"Skyramp Tester\",\"description\":\"Test Generation\",\"image_url\":\"images.google.com/skyramp.jpg\",\"category\":\"Software\",\"in_stock\":true,\"price\":999}",
|
|
130
|
+
"ResponseBody": "{\"name\":\"Skyramp Tester\",\"description\":\"Test Generation\",\"price\":999.0,\"image_url\":\"images.google.com/skyramp.jpg\",\"category\":\"Software\",\"in_stock\":true,\"product_id\":24,\"created_at\":\"2025-09-29T15:18:35.844599Z\",\"updated_at\":\"2025-09-29T15:18:35.844595Z\"}",
|
|
131
|
+
"RequestHeaders": {
|
|
132
|
+
"Content-Type": [
|
|
133
|
+
"application/json"
|
|
134
|
+
],
|
|
135
|
+
"Authorization": [
|
|
136
|
+
"Bearer flat-tropical-vapor"
|
|
137
|
+
]
|
|
138
|
+
},
|
|
139
|
+
"ResponseHeaders": {
|
|
140
|
+
"Content-Type": [
|
|
141
|
+
"application/json"
|
|
142
|
+
]
|
|
143
|
+
},
|
|
144
|
+
"Method": "POST",
|
|
145
|
+
"Path": "/api/v1/products",
|
|
146
|
+
"QueryParams": {},
|
|
147
|
+
"StatusCode": 201,
|
|
148
|
+
"Port": 443,
|
|
149
|
+
"Timestamp": "2025-09-29T15:18:36.178356292Z",
|
|
150
|
+
"Scheme": "https"
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"Source": "172.20.0.1:59186",
|
|
154
|
+
"Destination": "demoshop.skyramp.dev",
|
|
155
|
+
"RequestBody": "{\"customer_email\":\"kolja@skyramp.dev\",\"items\":[{\"product_id\":\"24\",\"quantity\":1}]}",
|
|
156
|
+
"ResponseBody": "{\"customer_email\":\"kolja@skyramp.dev\",\"status\":\"pending\",\"total_amount\":999.0,\"order_id\":13,\"items\":[{\"quantity\":1,\"product_id\":24,\"order_item_id\":24,\"order_id\":13}],\"created_at\":\"2025-09-29T15:18:51.024822\",\"updated_at\":\"2025-09-29T15:18:51.024827\"}",
|
|
157
|
+
"RequestHeaders": {
|
|
158
|
+
"Content-Type": [
|
|
159
|
+
"application/json"
|
|
160
|
+
],
|
|
161
|
+
"Authorization": [
|
|
162
|
+
"Bearer flat-tropical-vapor"
|
|
163
|
+
]
|
|
164
|
+
},
|
|
165
|
+
"ResponseHeaders": {
|
|
166
|
+
"Content-Type": [
|
|
167
|
+
"application/json"
|
|
168
|
+
]
|
|
169
|
+
},
|
|
170
|
+
"Method": "POST",
|
|
171
|
+
"Path": "/api/v1/orders",
|
|
172
|
+
"QueryParams": {},
|
|
173
|
+
"StatusCode": 201,
|
|
174
|
+
"Port": 443,
|
|
175
|
+
"Timestamp": "2025-09-29T15:18:51.328564007Z",
|
|
176
|
+
"Scheme": "https"
|
|
177
|
+
}
|
|
178
|
+
]
|
|
179
|
+
|
|
180
|
+
|
|
109
181
|
**IMPORTANT:**
|
|
110
182
|
- WHEN GENERATING TESTS USING TRACE, EXCLUDE THE PATHS THAT ARE NOT API ENDPOINTS.
|
|
183
|
+
- FOR SCENARIO PARSING, ENSURE THAT THE GENERATED REQUEST BODIES IN THE TRACE FILE MATCH THE API SCHEMA.
|
|
184
|
+
- FOR SCENARIO PARSING, ENSURE THAT THE ID FIELDS ARE PROPERLY CHAINED BETWEEN THE REQUESTS AND ALWAYS USE product_id=24.
|
|
185
|
+
- FOR SCENARIO PARSING, ALWAYS REQUIRE AN API SCHEMA FOR ACCURATE ENDPOINT MAPPING.
|
|
186
|
+
- SCENARIO PARSING ONLY RETURNS JSON ARRAYS - USE OTHER TOOLS FOR ACTUAL TEST GENERATION.
|
|
111
187
|
|
|
112
188
|
**CRITICAL: SHOW STEPS TO START/STOP PLAYWRIGHT TRACE COLLECTION FOR UI TESTS. NEVER SHOW THE CLI COMMANDS.**
|
|
113
189
|
`,
|
|
@@ -1,14 +1,35 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TestType } from "../types/TestTypes.js";
|
|
2
|
+
import { getModularizationPrompt as getModularizationPromptForUI } from "../prompts/modularization/ui-test-modularization.js";
|
|
3
|
+
import { getModularizationPrompt as getModularizationPromptForIntegration } from "../prompts/modularization/integration-test-modularization.js";
|
|
4
|
+
import { logger } from "../utils/logger.js";
|
|
2
5
|
export class ModularizationService {
|
|
3
|
-
constructor() { }
|
|
4
6
|
async processModularizationRequest(params) {
|
|
7
|
+
logger.info("Processing modularization request", {
|
|
8
|
+
testFile: params.testFile,
|
|
9
|
+
testType: params.testType,
|
|
10
|
+
language: params.language,
|
|
11
|
+
});
|
|
12
|
+
let prompt = "";
|
|
13
|
+
const testType = params.testType;
|
|
14
|
+
switch (testType) {
|
|
15
|
+
case TestType.UI:
|
|
16
|
+
prompt = getModularizationPromptForUI(params.testFile);
|
|
17
|
+
break;
|
|
18
|
+
case TestType.E2E:
|
|
19
|
+
prompt = getModularizationPromptForUI(params.testFile);
|
|
20
|
+
break;
|
|
21
|
+
case TestType.INTEGRATION:
|
|
22
|
+
prompt = getModularizationPromptForIntegration(params.testFile);
|
|
23
|
+
break;
|
|
24
|
+
default:
|
|
25
|
+
prompt = "";
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
5
28
|
return {
|
|
6
29
|
content: [
|
|
7
30
|
{
|
|
8
31
|
type: "text",
|
|
9
|
-
text:
|
|
10
|
-
? getModularizationPromptForUI(params.testFile, params.language)
|
|
11
|
-
: getModularizationPrompt(params.testFile, params.language)}`,
|
|
32
|
+
text: prompt,
|
|
12
33
|
},
|
|
13
34
|
],
|
|
14
35
|
};
|