Skip to main content
Glama

MCP Frontend Testing Server

generator.ts5.72 kB
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { z } from 'zod'; import { performCodeAnalysis } from './analyzer.js'; export function registerGeneratorTool(server: McpServer): void { server.tool( 'generateTest', { code: z.string(), framework: z.enum(['jest', 'cypress']), type: z.enum(['unit', 'component', 'e2e']), language: z.enum(['javascript', 'typescript', 'jsx', 'tsx']).default('javascript'), description: z.string().optional() }, async ({ code, framework, type, language, description }) => { try { const testCode = generateTestCode(code, framework, type, language, description); return { content: [{ type: 'text', text: testCode, }], }; } catch (error) { return { isError: true, content: [{ type: 'text', text: `Error generating test: ${String(error)}`, }], }; } } ); } // Helper function to generate test code based on source code and parameters // eslint-disable-next-line @typescript-eslint/no-explicit-any export function generateTestCode( sourceCode: string, framework: string, testType: string, language: string, description?: string ): string { // Analyze the code to better understand its structure const analysis = performCodeAnalysis(sourceCode, language); // Extract component or function name const nameMatch = sourceCode.match(/(?:function|class|const)\s+(\w+)/); const name = nameMatch ? nameMatch[1] : 'Component'; // Generate appropriate import statements based on framework and test type let imports = ''; let testCode = ''; if (framework === 'jest') { if (testType === 'unit') { imports = `// Import the module to test\n${language.includes('typescript') ? `import { ${name} } from './${name}';` : `const ${name} = require('./${name}');`}`; testCode = `describe('${name}', () => { test('${description || 'should work correctly'}', () => { // Arrange ${(analysis as any)?.codeType?.isFunction ? ` // Example test input const input = 'test'; // Act const result = ${name}(input); // Assert expect(result).toBeDefined();` : ` // Setup any required state // Act - perform the action // Assert - check the result expect(true).toBe(true);`} }); ${(analysis as any)?.complexity?.hasAsync ? ` test('handles async operations', async () => { // Arrange // Act const result = await ${name}(); // Assert expect(result).toBeDefined(); });` : ''} });`; } else if (testType === 'component') { imports = `import { render, screen${(analysis as any)?.complexity?.hasEvents ? ', fireEvent' : ''} } from '@testing-library/react';\n${(analysis as any)?.complexity?.hasEvents ? `import userEvent from '@testing-library/user-event';` : ''}\n${language.includes('typescript') ? `import { ${name} } from './${name}';` : `import { default as ${name} } from './${name}';`}`; testCode = `describe('${name}', () => { test('renders correctly', () => { // Arrange render(<${name} />); // Assert expect(screen.getByText(/content/i)).toBeInTheDocument(); }); ${(analysis as any).complexity?.hasEvents ? ` test('handles user interaction', async () => { // Arrange render(<${name} />); // Act await userEvent.click(screen.getByRole('button')); // Assert expect(screen.getByText(/result/i)).toBeInTheDocument(); });` : ''} ${(analysis as any)?.complexity?.hasAsync ? ` test('loads data asynchronously', async () => { // Arrange render(<${name} />); // Act - wait for async operation await screen.findByText(/loaded/i); // Assert expect(screen.getByText(/loaded/i)).toBeInTheDocument(); });` : ''} });`; } } else if (framework === 'cypress') { if (testType === 'component') { imports = `${language.includes('typescript') ? `import { ${name} } from './${name}';` : `import Component from './Component';`}`; testCode = `describe('${name}', () => { it('renders correctly', () => { // Arrange cy.mount(<${name} />); // Assert cy.contains(/content/i).should('be.visible'); }); ${(analysis as any)?.complexity?.hasEvents ? ` it('handles user interaction', () => { // Arrange cy.mount(<${name} />); // Act cy.get('button').click(); // Assert cy.contains(/result/i).should('be.visible'); });` : ''} ${(analysis as any)?.complexity?.hasAsync ? ` it('loads data asynchronously', () => { // Arrange cy.mount(<${name} />); // Assert - wait for async operation cy.contains(/loaded/i, { timeout: 10000 }).should('be.visible'); });` : ''} });`; } else if (testType === 'e2e') { imports = '// No imports needed for Cypress E2E tests'; testCode = `describe('${name} E2E Test', () => { beforeEach(() => { // Visit the page containing the component cy.visit('/'); }); it('${description || 'works correctly'}', () => { // Assert the component is rendered cy.contains(/content/i).should('be.visible'); ${(analysis as any)?.complexity?.hasEvents ? ` // Act - interact with the component cy.get('button').click(); // Assert the interaction worked cy.contains(/result/i).should('be.visible');` : ''} ${(analysis as any)?.complexity?.hasAsync ? ` // Assert async data loads correctly cy.contains(/loaded/i, { timeout: 10000 }).should('be.visible');` : ''} }); });`; } } // Combine imports and test code return `${imports}\n${testCode}`; }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/StudentOfJS/mcp-frontend-testing'

If you have feedback or need assistance with the MCP directory API, please join our Discord server