@democratize-quality/mcp-server 1.1.9 → 1.2.0

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.
Files changed (62) hide show
  1. package/dist/server.d.ts +41 -0
  2. package/dist/server.d.ts.map +1 -0
  3. package/dist/server.js +225 -0
  4. package/dist/server.js.map +1 -0
  5. package/package.json +23 -24
  6. package/browserControl.js +0 -113
  7. package/cli.js +0 -228
  8. package/mcpServer.js +0 -335
  9. package/run-server.js +0 -140
  10. package/src/chatmodes//360/237/214/220 api-generator.chatmode.md" +0 -409
  11. package/src/chatmodes//360/237/214/220 api-healer.chatmode.md" +0 -494
  12. package/src/chatmodes//360/237/214/220 api-planner.chatmode.md" +0 -954
  13. package/src/config/environments/api-only.js +0 -53
  14. package/src/config/environments/development.js +0 -54
  15. package/src/config/environments/production.js +0 -69
  16. package/src/config/index.js +0 -341
  17. package/src/config/server.js +0 -41
  18. package/src/config/tools/api.js +0 -67
  19. package/src/config/tools/browser.js +0 -90
  20. package/src/config/tools/default.js +0 -32
  21. package/src/docs/Agent_README.md +0 -310
  22. package/src/docs/QUICK_REFERENCE.md +0 -111
  23. package/src/services/browserService.js +0 -325
  24. package/src/skills/api-planning/SKILL.md +0 -224
  25. package/src/skills/test-execution/SKILL.md +0 -777
  26. package/src/skills/test-generation/SKILL.md +0 -309
  27. package/src/skills/test-healing/SKILL.md +0 -405
  28. package/src/tools/api/api-generator.js +0 -1865
  29. package/src/tools/api/api-healer.js +0 -617
  30. package/src/tools/api/api-planner.js +0 -2598
  31. package/src/tools/api/api-project-setup.js +0 -313
  32. package/src/tools/api/api-request.js +0 -641
  33. package/src/tools/api/api-session-report.js +0 -1278
  34. package/src/tools/api/api-session-status.js +0 -395
  35. package/src/tools/api/prompts/README.md +0 -293
  36. package/src/tools/api/prompts/generation-prompts.js +0 -703
  37. package/src/tools/api/prompts/healing-prompts.js +0 -195
  38. package/src/tools/api/prompts/index.js +0 -25
  39. package/src/tools/api/prompts/orchestrator.js +0 -334
  40. package/src/tools/api/prompts/validation-rules.js +0 -339
  41. package/src/tools/base/ToolBase.js +0 -230
  42. package/src/tools/base/ToolRegistry.js +0 -269
  43. package/src/tools/browser/advanced/browser-console.js +0 -384
  44. package/src/tools/browser/advanced/browser-dialog.js +0 -319
  45. package/src/tools/browser/advanced/browser-evaluate.js +0 -337
  46. package/src/tools/browser/advanced/browser-file.js +0 -480
  47. package/src/tools/browser/advanced/browser-keyboard.js +0 -343
  48. package/src/tools/browser/advanced/browser-mouse.js +0 -332
  49. package/src/tools/browser/advanced/browser-network.js +0 -421
  50. package/src/tools/browser/advanced/browser-pdf.js +0 -407
  51. package/src/tools/browser/advanced/browser-tabs.js +0 -497
  52. package/src/tools/browser/advanced/browser-wait.js +0 -378
  53. package/src/tools/browser/click.js +0 -168
  54. package/src/tools/browser/close.js +0 -60
  55. package/src/tools/browser/dom.js +0 -70
  56. package/src/tools/browser/launch.js +0 -67
  57. package/src/tools/browser/navigate.js +0 -270
  58. package/src/tools/browser/screenshot.js +0 -351
  59. package/src/tools/browser/type.js +0 -174
  60. package/src/tools/index.js +0 -95
  61. package/src/utils/agentInstaller.js +0 -418
  62. package/src/utils/browserHelpers.js +0 -83
@@ -1,195 +0,0 @@
1
- /**
2
- * Healing Prompts - Fix issues in generated code
3
- *
4
- * These prompts are used to fix validation errors in generated code.
5
- * Applied when validation fails, with specific feedback about issues.
6
- */
7
-
8
- module.exports = {
9
- /**
10
- * Heal Playwright test code issues
11
- */
12
- playwrightHealing: {
13
- system: `You are a code fixing expert for REST and GraphQL API tests. Fix the issues in the generated Playwright test code while maintaining functionality.
14
-
15
- Requirements:
16
- - Support both REST and GraphQL API testing patterns
17
- - For GraphQL: POST method with { query: "...", variables: {...} } body
18
- - For GraphQL: Validate response has 'data' or 'errors' property
19
- - Fix ONLY the reported issues
20
- - Maintain all existing functionality
21
- - Keep the same code structure
22
- - Use proper indentation (6 spaces for test body)
23
- - Return ONLY the fixed code, no explanations
24
- - DO NOT create any additional files
25
- - DO NOT generate README, SUMMARY, or documentation`,
26
-
27
- user: (context) => {
28
- const { originalCode, issues, scenario } = context;
29
-
30
- let prompt = `Fix the following issues in this Playwright test code:
31
-
32
- **Original Code:**
33
- \`\`\`typescript
34
- ${originalCode}
35
- \`\`\`
36
-
37
- **Issues Found:**
38
- ${issues.map((issue, i) => `${i + 1}. [${issue.severity.toUpperCase()}] ${issue.message}
39
- Fix: ${issue.fix}`).join('\n')}
40
-
41
- **Original Scenario Context:**
42
- - API Type: ${scenario.isGraphQL ? 'GraphQL' : 'REST'}
43
- - Method: ${scenario.method}
44
- - Endpoint: ${scenario.endpoint}
45
- - Expected Status: ${scenario.expect?.status || 200}
46
-
47
- `;
48
-
49
- // NEW: GraphQL-specific healing guidance
50
- if (scenario.isGraphQL && scenario.graphql) {
51
- prompt += `**GraphQL-Specific Requirements:**
52
- This is a GraphQL test. Ensure:
53
- 1. Uses POST method (not ${scenario.method})
54
- 2. Endpoint is: ${scenario.endpoint || '/graphql'}
55
- 3. Request body structure:
56
- \`\`\`javascript
57
- data: {
58
- query: \`${scenario.graphql.query.replace(/`/g, '\\`')}\`,
59
- variables: ${JSON.stringify(scenario.graphql.variables, null, 6)}
60
- }
61
- \`\`\`
62
- 4. Response validation:
63
- - For success: expect(responseData).toHaveProperty('data')
64
- - For errors: expect(responseData).toHaveProperty('errors')
65
-
66
- `;
67
- }
68
-
69
- prompt += `**Instructions:**
70
- 1. Fix ALL reported issues
71
- 2. Maintain the same functionality
72
- 3. Keep proper indentation (6 spaces)
73
- 4. For URL construction, use template literals: \`\${baseUrl}/endpoint\`
74
- 5. Ensure await is used for all async calls
75
- 6. Return ONLY the fixed code, starting at line 1 of the test body
76
-
77
- DO NOT:
78
- - Add explanations or comments about fixes
79
- - Change the test logic
80
- - Add or remove functionality
81
- - Include test() wrapper or imports
82
- - Create any additional files (README, SUMMARY, GUIDE, etc.)
83
- - Suggest file creation
84
-
85
- Return the complete fixed test body code.`;
86
-
87
- return prompt;
88
- }
89
- },
90
-
91
- /**
92
- * Heal Jest test code issues
93
- */
94
- jestHealing: {
95
- system: `You are a code fixing expert for REST and GraphQL API tests. Fix the issues in the generated Jest test code while maintaining functionality.
96
-
97
- Requirements:
98
- - Support both REST and GraphQL API testing patterns
99
- - For GraphQL: POST method with { query: "...", variables: {...} } in data field
100
- - For GraphQL: Validate response.data has 'data' or 'errors' property
101
- - Fix ONLY the reported issues
102
- - Maintain all existing functionality
103
- - Keep the same code structure
104
- - Use proper indentation (6 spaces for test body)
105
- - Return ONLY the fixed code, no explanations
106
- - DO NOT create any additional files
107
- - DO NOT generate README, SUMMARY, or documentation`,
108
-
109
- user: (context) => {
110
- const { originalCode, issues, scenario } = context;
111
-
112
- let prompt = `Fix the following issues in this Jest test code:
113
-
114
- **Original Code:**
115
- \`\`\`typescript
116
- ${originalCode}
117
- \`\`\`
118
-
119
- **Issues Found:**
120
- ${issues.map((issue, i) => `${i + 1}. [${issue.severity.toUpperCase()}] ${issue.message}
121
- Fix: ${issue.fix}`).join('\n')}
122
-
123
- **Original Scenario Context:**
124
- - API Type: ${scenario.isGraphQL ? 'GraphQL' : 'REST'}
125
- - Method: ${scenario.method}
126
- - Endpoint: ${scenario.endpoint}
127
- - Expected Status: ${scenario.expect?.status || 200}
128
-
129
- `;
130
-
131
- // NEW: GraphQL-specific healing guidance for Jest
132
- if (scenario.isGraphQL && scenario.graphql) {
133
- prompt += `**GraphQL-Specific Requirements:**
134
- This is a GraphQL test. Ensure:
135
- 1. Uses POST method in makeRequest: method: 'POST'
136
- 2. URL is: '${scenario.endpoint || '/graphql'}'
137
- 3. Request data structure:
138
- \`\`\`javascript
139
- data: {
140
- query: \`${scenario.graphql.query.replace(/`/g, '\\`')}\`,
141
- variables: ${JSON.stringify(scenario.graphql.variables, null, 6)}
142
- }
143
- \`\`\`
144
- 4. Response validation:
145
- - For success: expect(response.data).toHaveProperty('data')
146
- - For errors: expect(response.data).toHaveProperty('errors')
147
-
148
- `;
149
- }
150
-
151
- prompt += `**Instructions:**
152
- 1. Fix ALL reported issues
153
- 2. Maintain the same functionality
154
- 3. Keep proper indentation (6 spaces)
155
- 4. Use apiUtils.makeRequest() correctly
156
- 5. Ensure await is used for all async calls
157
- 6. Return ONLY the fixed code, starting at line 1 of the test body
158
-
159
- DO NOT:
160
- - Add explanations or comments about fixes
161
- - Change the test logic
162
- - Add or remove functionality
163
- - Include test() wrapper or imports
164
- - Create any additional files (README, SUMMARY, GUIDE, etc.)
165
- - Suggest file creation
166
-
167
- Return the complete fixed test body code.`;
168
-
169
- return prompt;
170
- }
171
- },
172
-
173
- /**
174
- * Generic healing prompt for any format
175
- */
176
- genericHealing: {
177
- system: `You are a code fixing expert. Fix the reported issues in the code while maintaining all functionality.`,
178
-
179
- user: (context) => {
180
- const { originalCode, issues, format, language } = context;
181
-
182
- return `Fix these issues in ${format} ${language} code:
183
-
184
- **Issues:**
185
- ${issues.map((issue, i) => `${i + 1}. ${issue.message} - Fix: ${issue.fix}`).join('\n')}
186
-
187
- **Code:**
188
- \`\`\`${language}
189
- ${originalCode}
190
- \`\`\`
191
-
192
- Return the fixed code only, no explanations.`;
193
- }
194
- }
195
- };
@@ -1,25 +0,0 @@
1
- /**
2
- * Prompt Orchestration System
3
- *
4
- * Exports all components of the prompt orchestration system for AI-based test generation.
5
- *
6
- * @module prompts
7
- */
8
-
9
- const generationPrompts = require('./generation-prompts');
10
- const validationRules = require('./validation-rules');
11
- const healingPrompts = require('./healing-prompts');
12
- const PromptOrchestrator = require('./orchestrator');
13
-
14
- module.exports = {
15
- // Main orchestrator class
16
- PromptOrchestrator,
17
-
18
- // Individual components
19
- generationPrompts,
20
- validationRules,
21
- healingPrompts,
22
-
23
- // Convenience factory
24
- createOrchestrator: (options) => new PromptOrchestrator(options)
25
- };
@@ -1,334 +0,0 @@
1
- /**
2
- * Prompt Orchestrator
3
- *
4
- * Coordinates the Planning → Generation → Validation → Healing workflow
5
- * for AI-based test code generation.
6
- */
7
-
8
- const generationPrompts = require('./generation-prompts');
9
- const validationRules = require('./validation-rules');
10
- const healingPrompts = require('./healing-prompts');
11
-
12
- class PromptOrchestrator {
13
- constructor(options = {}) {
14
- this.maxHealingAttempts = options.maxHealingAttempts || 3;
15
- this.language = options.language || 'typescript';
16
- this.outputFormat = options.outputFormat || 'playwright';
17
- this.verbose = options.verbose || false;
18
- }
19
-
20
- /**
21
- * Generate test code with validation and healing
22
- *
23
- * Workflow:
24
- * 1. Generate code using AI
25
- * 2. Validate generated code
26
- * 3. If invalid, heal and retry (up to maxHealingAttempts)
27
- * 4. Return validated code or fallback
28
- */
29
- async generateTestCode(context, aiGenerator) {
30
- const { scenario, baseUrl } = context;
31
-
32
- this.log(`📝 Generating ${this.outputFormat} test for: ${scenario.title}`);
33
-
34
- // Step 1: Generate initial code
35
- let generatedCode = await this._generateCode(context, aiGenerator);
36
-
37
- // Step 1.5: Validate single file output (SAFETY NET)
38
- // Some helpful AI models try to create README, SUMMARY, etc.
39
- generatedCode = this._validateSingleFileOutput(generatedCode, context.targetFile);
40
-
41
- // Step 2: Validate
42
- let validation = this._validateCode(generatedCode, context);
43
-
44
- // Step 3: Heal if needed (up to maxHealingAttempts)
45
- let healingAttempt = 0;
46
- while (!validation.valid && healingAttempt < this.maxHealingAttempts) {
47
- healingAttempt++;
48
- this.log(`🔧 Healing attempt ${healingAttempt}/${this.maxHealingAttempts}...`);
49
- this.log(` Issues: ${validation.issues.map(i => i.message).join(', ')}`);
50
-
51
- generatedCode = await this._healCode(generatedCode, validation.issues, context, aiGenerator);
52
- validation = this._validateCode(generatedCode, context);
53
-
54
- if (validation.valid) {
55
- this.log(`✅ Code healed successfully!`);
56
- }
57
- }
58
-
59
- // Step 4: Return result
60
- if (!validation.valid) {
61
- this.log(`⚠️ Warning: Code still has issues after ${healingAttempt} healing attempts`);
62
- this.log(` Remaining issues: ${validation.issues.map(i => i.message).join(', ')}`);
63
- }
64
-
65
- return {
66
- code: generatedCode,
67
- valid: validation.valid,
68
- issues: validation.issues,
69
- healingAttempts: healingAttempt,
70
- metadata: {
71
- scenario: scenario.title,
72
- format: this.outputFormat,
73
- language: this.language
74
- }
75
- };
76
- }
77
-
78
- /**
79
- * Generate code using AI
80
- */
81
- async _generateCode(context, aiGenerator) {
82
- const promptConfig = this._getGenerationPrompt();
83
-
84
- const systemPrompt = promptConfig.system;
85
- const userPrompt = promptConfig.user({
86
- ...context,
87
- language: this.language,
88
- options: { format: this.outputFormat }
89
- });
90
-
91
- this.log(`💭 Sending generation prompt to AI...`);
92
-
93
- // Call AI generator (this would be GitHub Copilot API, OpenAI, etc.)
94
- const code = await aiGenerator.generate(systemPrompt, userPrompt);
95
-
96
- return code.trim();
97
- }
98
-
99
- /**
100
- * Validate generated code
101
- */
102
- _validateCode(code, context) {
103
- this.log(`🔍 Validating generated code...`);
104
-
105
- const isGraphQL = context?.scenario?.isGraphQL || false;
106
- const validator = validationRules.getValidator(this.outputFormat);
107
- const validation = validator.validateAll(code, this.language, isGraphQL);
108
-
109
- if (validation.valid) {
110
- this.log(`✅ Code validation passed!`);
111
- } else {
112
- this.log(`❌ Code validation failed with ${validation.issues.length} issues`);
113
- }
114
-
115
- return validation;
116
- }
117
-
118
- /**
119
- * Heal code issues using AI
120
- */
121
- async _healCode(originalCode, issues, context, aiGenerator) {
122
- const healingConfig = this._getHealingPrompt();
123
-
124
- const systemPrompt = healingConfig.system;
125
- const userPrompt = healingConfig.user({
126
- originalCode,
127
- issues,
128
- scenario: context.scenario,
129
- format: this.outputFormat,
130
- language: this.language
131
- });
132
-
133
- this.log(`🏥 Sending healing prompt to AI...`);
134
-
135
- // Call AI generator for healing
136
- const healedCode = await aiGenerator.generate(systemPrompt, userPrompt);
137
-
138
- return healedCode.trim();
139
- }
140
-
141
- /**
142
- * Get generation prompt for current format
143
- */
144
- _getGenerationPrompt() {
145
- switch(this.outputFormat) {
146
- case 'playwright':
147
- return generationPrompts.playwrightScenario;
148
- case 'jest':
149
- return generationPrompts.jestScenario;
150
- case 'postman':
151
- return generationPrompts.postmanTestScript;
152
- default:
153
- throw new Error(`Unknown output format: ${this.outputFormat}`);
154
- }
155
- }
156
-
157
- /**
158
- * Get healing prompt for current format
159
- */
160
- _getHealingPrompt() {
161
- switch(this.outputFormat) {
162
- case 'playwright':
163
- return healingPrompts.playwrightHealing;
164
- case 'jest':
165
- return healingPrompts.jestHealing;
166
- default:
167
- return healingPrompts.genericHealing;
168
- }
169
- }
170
-
171
- /**
172
- * Log helper
173
- */
174
- log(message) {
175
- if (this.verbose) {
176
- console.log(message);
177
- }
178
- }
179
-
180
- /**
181
- * Generate full test file (with imports and structure)
182
- */
183
- generateTestFile(testBodies, testPlan, options = {}) {
184
- const { format, language, sessionId } = options;
185
-
186
- switch(format) {
187
- case 'playwright':
188
- return this._generatePlaywrightFile(testBodies, testPlan, language, sessionId);
189
- case 'jest':
190
- return this._generateJestFile(testBodies, testPlan, language, sessionId);
191
- default:
192
- throw new Error(`Unknown format: ${format}`);
193
- }
194
- }
195
-
196
- /**
197
- * Generate complete Playwright test file
198
- */
199
- _generatePlaywrightFile(testBodies, testPlan, language, sessionId) {
200
- const isTS = language === 'typescript';
201
- const imports = isTS
202
- ? `import { test, expect } from '@playwright/test';`
203
- : `const { test, expect } = require('@playwright/test');`;
204
-
205
- const testCases = testPlan.sections.flatMap((section, sectionIndex) =>
206
- section.scenarios.map((scenario, scenarioIndex) => {
207
- const testBody = testBodies[`${sectionIndex}-${scenarioIndex}`];
208
- return `
209
- test('${scenario.title}', async ({ request }) => {
210
- ${testBody}
211
- });`;
212
- }).join('\n')
213
- );
214
-
215
- return `// Generated API Tests for: ${testPlan.title}
216
- // Generated by Democratize Quality MCP Server (AI-Generated)
217
- // Session ID: ${sessionId}
218
- // Language: ${language}
219
-
220
- ${imports}
221
-
222
- test.describe('${testPlan.title} - API Tests', () => {
223
- const baseUrl = '${testPlan.baseUrl}';
224
- ${testCases}
225
- });`;
226
- }
227
-
228
- /**
229
- * Generate complete Jest test file
230
- */
231
- _generateJestFile(testBodies, testPlan, language, sessionId) {
232
- const isTS = language === 'typescript';
233
- const imports = isTS
234
- ? `import axios from 'axios';\nimport { ApiTestUtils } from './test-utils';`
235
- : `const axios = require('axios');\nconst { ApiTestUtils } = require('./test-utils');`;
236
-
237
- const typeAnnotation = isTS ? ': ApiTestUtils' : '';
238
-
239
- const testCases = testPlan.sections.flatMap((section, sectionIndex) =>
240
- section.scenarios.map((scenario, scenarioIndex) => {
241
- const testBody = testBodies[`${sectionIndex}-${scenarioIndex}`];
242
- return `
243
- test('${scenario.title}', async () => {
244
- ${testBody}
245
- });`;
246
- }).join('\n')
247
- );
248
-
249
- return `// Generated Jest API Tests for: ${testPlan.title}
250
- // Generated by Democratize Quality MCP Server (AI-Generated)
251
- // Session ID: ${sessionId}
252
- // Language: ${language}
253
-
254
- ${imports}
255
-
256
- describe('${testPlan.title} API Tests', () => {
257
- let apiUtils${typeAnnotation};
258
- const baseUrl = '${testPlan.baseUrl}';
259
-
260
- beforeAll(async () => {
261
- apiUtils = new ApiTestUtils(baseUrl);
262
- console.log('Test suite initialized');
263
- });
264
-
265
- afterAll(async () => {
266
- await apiUtils.cleanup();
267
- console.log('Test suite completed');
268
- });
269
-
270
- describe('Test Scenarios', () => {${testCases}
271
- });
272
- });`;
273
- }
274
-
275
- /**
276
- * Validate that AI generated ONLY the requested file
277
- * Some helpful models try to create READMEs, summaries, etc.
278
- * This is a safety net in case prompts are ignored.
279
- *
280
- * @param {string} generatedCode - The generated code from AI
281
- * @param {string} targetFileName - The expected file name
282
- * @returns {string} - Filtered code with only the test file
283
- */
284
- _validateSingleFileOutput(generatedCode, targetFileName) {
285
- // Check for multiple file indicators
286
- const multiFilePatterns = [
287
- /(?:create|generate|add)\s+(?:a\s+)?(?:README|SUMMARY|GUIDE|NOTES)/i,
288
- /(?:also|additionally),?\s+(?:create|generate|write)/i,
289
- /^#+\s+(?:README|SUMMARY|Quick Reference|Guide)/m,
290
- /File:\s+[A-Z_-]+\.md/i,
291
- /```[a-z]*\s*\n#+\s+(?:README|Summary)/i,
292
- /\*\*File:\*\*\s+(?:README|SUMMARY|GUIDE)/i
293
- ];
294
-
295
- for (const pattern of multiFilePatterns) {
296
- if (pattern.test(generatedCode)) {
297
- this.log(`⚠️ Warning: AI attempted to create additional files - filtering...`);
298
- // Extract just the test code, ignore suggestions
299
- return this._extractTestCodeOnly(generatedCode);
300
- }
301
- }
302
-
303
- return generatedCode;
304
- }
305
-
306
- /**
307
- * Extract only the actual test code from AI output
308
- * Remove any file creation suggestions or documentation
309
- *
310
- * @param {string} output - The full AI output
311
- * @returns {string} - Extracted test code only
312
- */
313
- _extractTestCodeOnly(output) {
314
- // Look for code fence or actual code
315
- const codeFenceMatch = output.match(/```(?:typescript|javascript|ts|js)?\n([\s\S]+?)```/);
316
- if (codeFenceMatch) {
317
- this.log(`✅ Extracted test code from code fence`);
318
- return codeFenceMatch[1];
319
- }
320
-
321
- // Try to find the test code by looking for test.describe or describe
322
- const testDescribeMatch = output.match(/((?:test\.)?describe\(['"`][\s\S]+?\n\}\);)/);
323
- if (testDescribeMatch) {
324
- this.log(`✅ Extracted test code by pattern matching`);
325
- return testDescribeMatch[1];
326
- }
327
-
328
- // If no extraction possible, return as-is but warn
329
- this.log(`⚠️ Could not extract test code - returning full output`);
330
- return output;
331
- }
332
- }
333
-
334
- module.exports = PromptOrchestrator;