@skyramp/mcp 0.0.31 → 0.0.33

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 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
- resources: {},
26
- tools: {},
27
- prompts: {},
28
- sampling: {},
29
- elicitation: {},
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);
@@ -56,6 +61,20 @@ async function main() {
56
61
  const transport = new StdioServerTransport();
57
62
  await server.connect(transport);
58
63
  logger.info("MCP Server started successfully");
64
+ // Listen for stdin closure (parent process disconnected)
65
+ process.stdin.on("end", () => {
66
+ logger.info("STDIN closed, parent process disconnected. Exiting...");
67
+ process.exit(0);
68
+ });
69
+ // Handle process termination signals
70
+ process.on("SIGTERM", () => {
71
+ logger.info("Received SIGTERM, shutting down gracefully...");
72
+ process.exit(0);
73
+ });
74
+ process.on("SIGINT", () => {
75
+ logger.info("Received SIGINT, shutting down gracefully...");
76
+ process.exit(0);
77
+ });
59
78
  }
60
79
  main().catch((error) => {
61
80
  logger.critical("Fatal error in main()", {
@@ -0,0 +1,151 @@
1
+ import { generateSkyrampHeader, SKYRAMP_UTILS_HEADER } from "../utils/utils.js";
2
+ const LANGUAGE_MAP = {
3
+ python: {
4
+ extension: "py",
5
+ fileName: "SkyrampUtils.py",
6
+ },
7
+ java: {
8
+ extension: "java",
9
+ fileName: "SkyrampUtils.java",
10
+ },
11
+ javascript: {
12
+ extension: "js",
13
+ fileName: "skyrampUtils.js",
14
+ },
15
+ typescript: {
16
+ extension: "ts",
17
+ fileName: "skyrampUtils.ts",
18
+ },
19
+ };
20
+ export function getCodeReusePrompt(testFile, language) {
21
+ const ext = LANGUAGE_MAP[language].extension || "py";
22
+ const fileName = LANGUAGE_MAP[language].fileName || "SkyrampUtils.py";
23
+ return `# CODE REUSE - 6 CLEAR STEPS
24
+ **CRITICAL WARNING: VIOLATION OF THESE RULES WILL RESULT IN ERROR**
25
+
26
+ ## DEFINITIONS (READ FIRST):
27
+ **What is a "Helper Function"?**
28
+ - A helper function is a STANDALONE, DISTINCT function that is ALREADY DEFINED in the code
29
+ - It has a clear function signature (e.g., \`async function createProduct(page, data) { ... }\`)
30
+ - It is NOT just repetitive inline test code or patterns
31
+ - Example of helper function: \`async function loginUser(page, email, password) { ... }\`
32
+ - Example of NOT a helper function: Repetitive \`await page.click()\` statements scattered in test
33
+
34
+ **What is "Repetitive Code Pattern"?**
35
+ - Sequential test steps that look similar but are NOT extracted into standalone functions
36
+ - Example: Multiple sequences of \`await page.fill()\`, \`await page.click()\` directly in test body
37
+ - These patterns should NOT be extracted during code reuse - that's what modularization is for
38
+
39
+ 🚨 **CODE REUSE ≠ REFACTORING** 🚨
40
+ - Code reuse = Finding EXISTING helper functions and reusing them
41
+ - Refactoring = Creating NEW helper functions from patterns (handled by modularization tool)
42
+
43
+ ## STEP 1: READ TEST FILE
44
+ Read ${testFile} and look for ALREADY DEFINED helper functions (not just repetitive patterns).
45
+
46
+ ## STEP 2: FIND EXISTING UTILS
47
+ Use the Grep tool to search for files containing "${SKYRAMP_UTILS_HEADER}":
48
+ - Pattern: "${SKYRAMP_UTILS_HEADER}"
49
+ - Type: "${ext}"
50
+ - Output mode: "files_with_matches"
51
+ **CRITICAL: Only look for util files with header ${SKYRAMP_UTILS_HEADER}** - exclude test files (files with "test", "spec", ".test.", ".spec." in the name).
52
+ Read the matching non-test files and check if any helpers can be reused in ${testFile}.
53
+
54
+ ## STEP 3: USE EXISTING HELPERS FROM UTILS SOURCE FILES FOUND IN STEP 2
55
+ If helpers exist in util file that can be reused in ${testFile} without modifying them:
56
+ - Import them into ${testFile}
57
+ - Remove any duplicate code in ${testFile}
58
+ - Test that ${testFile} still works without any errors and logical is same as original test file.
59
+
60
+ ## STEP 4: FIND LOCAL HELPERS IN OTHER TEST SOURCE FILES THAT HAS HEADER ${SKYRAMP_UTILS_HEADER}
61
+ Use the Grep tool to search for other test files containing "${SKYRAMP_UTILS_HEADER}":
62
+ - Pattern: "${SKYRAMP_UTILS_HEADER}"
63
+ - Type: "${ext}"
64
+ - Output mode: "files_with_matches"
65
+ **CRITICAL: Exclude ${testFile} from the results** - only look at OTHER test files, not the current file.
66
+
67
+ 🚨 **STOP HERE IF NO OTHER TEST FILES FOUND** 🚨
68
+ **IF NO OTHER TEST FILES ARE FOUND, SKIP TO STEP 6 - DO NOT CREATE ANY UTILS FILES.**
69
+
70
+ If other test files are found, read those files and look for ALREADY DEFINED helper functions with clear function signatures.
71
+
72
+ **How to identify helper functions in other test files:**
73
+ ✅ HELPER FUNCTION (move to utils):
74
+ - Has function signature: \`async function doSomething(params) { ... }\`
75
+ - Can be called multiple times with different parameters
76
+ - Example: \`async function fillProductForm(page, product) { ... }\`
77
+
78
+ ❌ NOT A HELPER FUNCTION (do not extract):
79
+ - Just repetitive inline test code in test body
80
+ - No function definition/signature
81
+ - Example: Multiple \`await page.getByTestId("xyz").click()\` directly in test
82
+
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
+
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
+
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
+
94
+ 🚨 **IF ANY CONDITION IS NOT MET, SKIP TO STEP 6 - DO NOT CREATE ANY UTILS FILES.** 🚨
95
+
96
+ **Examples of when to SKIP STEP 5:**
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
+
102
+ **CRITICAL:** For helpers found in STEP 4:
103
+ 1. **CREATE** \`${fileName}\` file if it doesn't exist with the following header:
104
+ \`\`\`${ext}
105
+ ${generateSkyrampHeader(language)}
106
+ \`\`\`
107
+ **CRITICAL: IF \`${fileName}\` is already big, create a new file with a different name and add the header to the new file.**
108
+ 2. **COPY** those local helper functions from original test source files to \`${fileName}\` without modifying them
109
+ 3. **DELETE** those local helper functions from test source files (REMOVE THEM COMPLETELY) WITHOUT ANY OTHER CHANGES.
110
+ 4. **IMPORT** those local helper functions from \`${fileName}\` back into test source files WITHOUT MAKING ANY OTHER CHANGE.
111
+ 5. **IMPORT** those local helper functions from \`${fileName}\` into ${testFile}
112
+ 6. **REPLACE** duplicate code in ${testFile} with calls to imported helper functions WITHOUT MAKING ANY OTHER CHANGE.
113
+
114
+ 🚨 **CRITICAL: DO NOT CREATE UNNECESSARY HELPER FUNCTIONS** 🚨
115
+ 🚨 **DO NOT CREATE HELPERS BASED ON PATTERNS IN THE CURRENT FILE** 🚨
116
+
117
+ ## STEP 6: VERIFY AND VALIDATE
118
+ 1. **BEFORE** making any changes, read the original test file and identify ALL helper functions
119
+ 2. **AFTER** copying helpers to utils, read the original file again to confirm helpers are GONE
120
+ 3. **VERIFY** that helper functions are NO LONGER in original test files
121
+ 4. **VERIFY** that the original test files only have import statements and no duplicate code
122
+ 5. **VERIFY** that both original and new test files import from utils and use the helper functions
123
+ 6. **VERIFY** that no unnecessary helper functions were created (functions that duplicate existing functionality)
124
+ 7. **VERIFY** that all helper functions in utils are actually imported and used in the test files
125
+ 8. **REMOVE** any helper functions that are not being used after refactoring
126
+ 9. **NEVER** refactor, reorganize, or restructure existing source test files beyond moving helpers
127
+ 10. **RUN TESTS** to ensure functionality is preserved after refactoring
128
+
129
+ 🚨 **FINAL REMINDER: DO NOT CREATE HELPER FUNCTIONS FROM SCRATCH** 🚨
130
+ 🚨 **ONLY MOVE EXISTING HELPERS FROM OTHER TEST FILES** 🚨
131
+
132
+ **IMPORTANT NOTES:**
133
+ - The process is designed to REUSE existing helper functions, not create new ones
134
+ - If no existing helpers are found, the test file should remain unchanged
135
+ - Code reuse is about moving existing, working helper functions between files
136
+ - Never create helper functions based on patterns you see in the current test file
137
+ - Helper functions must have explicit function signatures/definitions
138
+ - Repetitive inline test code is NOT a helper function
139
+
140
+ **DECISION TREE:**
141
+ 1. Found existing utils file with helpers? → Import and use them (Step 3)
142
+ 2. Found other test files with ACTUAL helper functions? → Move to utils (Step 5)
143
+ 3. Found other test files with only repetitive patterns? → SKIP to Step 6, NO utils file
144
+ 4. Found no other test files? → SKIP to Step 6, NO utils file
145
+ 5. Other test files identical to current? → SKIP to Step 6, NO utils file
146
+
147
+ **MANDATORY**: After code reuse is complete, proceed to modularization by calling skyramp_modularization tool
148
+
149
+ SUMMARIZE THE CODE REUSE PROCESS AND THE RESULTS.
150
+ `;
151
+ }
@@ -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,164 @@
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, NEW FILES, OR NEW DATA STRUCTURES
8
+ - DO NOT CHANGE TEST LOGIC, DATA VALUES, CALCULATIONS, OR ASSERTIONS
9
+ - DO NOT CREATE/UPDATE DEPENDENCY FILES 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 test data including 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 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
+
47
+ ## STEP 3: EXTRACT INTO HELPERS
48
+
49
+ **GOLDEN RULE: Copy the original code exactly, only add parameters for values that differ**
50
+
51
+ **CRITICAL - AVOID BUGS:**
52
+ - Copy the code block EXACTLY as-is from the original test
53
+ - **VERIFY ALL field mappings** - EVERY \`.fill()\` must use the correct parameter
54
+ - ✅ CORRECT: quantity field → \`.fill(quantity.toString())\`
55
+ - ❌ WRONG: quantity field → \`.fill("12")\` then \`.fill(quantity.toString())\` - remove hardcoded "12"!
56
+ - ❌ WRONG: name field → \`.fill(description)\` - fields must match their data!
57
+ - **Replace ALL hardcoded values with parameters** - No leftover hardcoded fills
58
+ - **NEVER create new conditional logic** (no ternaries, no if/else, no loops to derive parameter values)
59
+ - **NEVER add logic that wasn't in the original code**
60
+ - Keep ALL existing logic, calculations, and assertions unchanged
61
+ - Keep ALL lines in the same order (except: remove fills with wrong/temporary hardcoded values)
62
+
63
+ **PARAMETERIZATION BEST PRACTICES:**
64
+ 1. **Use individual parameters, not data objects** - Makes helper usage clearer
65
+ - ✅ GOOD: \`createProduct(page, name, price, category)\`
66
+ - ❌ BAD: \`createProduct(page, productData)\` - unclear what fields are needed
67
+
68
+ 2. **Avoid nested helpers** - Keep helpers flat and independent
69
+ - ✅ GOOD: One helper does the complete operation
70
+ - ❌ BAD: Helper calls another helper - adds complexity
71
+
72
+ 3. **No duplicate helpers** - If you have 2+ helpers doing similar things, consolidate them
73
+ - ✅ GOOD: One \`createOrder(email, items)\` handles both simple and complex orders
74
+ - ❌ BAD: \`createSimpleOrder\` and \`createOrderWithItems\` - consolidate into one
75
+ - Exception: Keep separate if it significantly improves readability
76
+
77
+ 4. **For repetitive code**: Only parameterize values that DIFFER between occurrences
78
+
79
+ 5. **NEVER compute parameters**: Pass literal values directly, don't create logic to derive them
80
+
81
+ 6. **If you need conditionals to choose parameter values, extract each case separately instead**
82
+
83
+ 7. **Loops in helpers**: Generally avoid, but acceptable if:
84
+ - The loop existed in the original code, OR
85
+ - It significantly improves readability without changing test behavior
86
+ - Example: Looping through order items is acceptable if each item is explicitly listed at call site
87
+
88
+ **NAVIGATION RULE:**
89
+ - Keep \`navbar-\` clicks and main \`page.goto\` in the test body
90
+ - Exception: Helper can include \`page.goto\` to navigate back after form submissions that redirect
91
+
92
+ **WRONG - Bad practices:**
93
+ \`\`\`typescript
94
+ // ❌ DON'T DO THIS - Adding conditional logic to handle multiple cases
95
+ async function addItem(page, index: number) {
96
+ const name = index === 1 ? "item1" : index === 2 ? "item2" : "item3";
97
+ await page.fill("#name", name);
98
+ }
99
+
100
+ // ❌ DON'T DO THIS - Duplicate actions
101
+ async function createProduct(page, name) {
102
+ await page.click("#add-button"); // Helper clicks button
103
+ // ... rest of product creation
104
+ }
105
+ // Then in test:
106
+ await page.click("#add-button"); // Test ALSO clicks button - DUPLICATE!
107
+ await createProduct(page, "item1");
108
+
109
+ // ❌ DON'T DO THIS - Multiple helpers for same operation
110
+ async function createSimpleOrder(...) { }
111
+ async function createOrderWithItems(...) { }
112
+ // Should be ONE helper: createOrder(page, email, items)
113
+ \`\`\`
114
+
115
+ **RIGHT - Good practices:**
116
+ \`\`\`typescript
117
+ // ✅ CORRECT - Extract with parameter, no new logic
118
+ async function addItem(page, name: string) {
119
+ await page.fill("#name", name); // Replace literal with parameter
120
+ }
121
+
122
+ // ✅ CORRECT - Call helper for EACH original occurrence
123
+ await addItem(page, "item1");
124
+ await addItem(page, "item2");
125
+ await addItem(page, "item3");
126
+
127
+ \`\`\`
128
+
129
+ ## STEP 4: CALL HELPERS WITH EXACT SAME VALUES
130
+ Use the EXACT same values from the original test when calling helpers.
131
+
132
+ ## STEP 5: VERIFY - CRITICAL CHECKS
133
+
134
+ **BUGS TO AVOID:**
135
+ - [ ] **ALL field mappings verified** - EVERY \`.fill()\` uses the correct parameter. Check field gets quantity parameter, NOT hardcoded
136
+ - [ ] **No duplicate helpers** - Consolidate similar helpers (e.g., one createOrder vs createSimpleOrder + createOrderWithItems)
137
+ - [ ] **No nested helpers** - Helpers don't call other helpers unnecessarily
138
+ - [ ] **Clear parameters** - Individual parameters (name, price) not data objects
139
+ - [ ] **No duplicate actions** - Don't click "Add Product" button in test AND in helper - choose one place
140
+ - [ ] **No new loops** - Exception: acceptable if it improves readability and items are explicit at call site
141
+
142
+ **DATA INTEGRITY:**
143
+ - [ ] Helpers are exact copies of original + parameters only
144
+ - [ ] All data values match the original test exactly
145
+ - [ ] All calculations produce identical results
146
+ - [ ] Helper calls use the same values as original
147
+ - [ ] No navigation code in helpers (except page.goto for state)
148
+ - [ ] No duplicate code in main test
149
+
150
+ **READABILITY:**
151
+ - [ ] Helper names clearly describe what they do
152
+ - [ ] Test flow is easy to follow
153
+ - [ ] Helper signatures are clear (individual params > data objects)
154
+
155
+ **FINAL CHECK:**
156
+ 1. Does the modularized test perform the exact same operations?
157
+ 2. With the exact same data?
158
+ 3. Expecting the exact same results?
159
+ 4. Is it MORE readable than the original?
160
+
161
+ If ANY answer is "no", fix it before submitting.
162
+
163
+ **When in doubt, don't extract - keep original code unchanged.**`;
164
+ }
@@ -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 { getModularizationPrompt, getModularizationPromptForUI, } from "../prompts/modularization-prompts.js";
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: `${params.testType === "ui"
10
- ? getModularizationPromptForUI(params.testFile, params.language)
11
- : getModularizationPrompt(params.testFile, params.language)}`,
32
+ text: prompt,
12
33
  },
13
34
  ],
14
35
  };