UNPKG

@executeautomation/playwright-mcp-server

Version:
159 lines (157 loc) 5.79 kB
import * as path from 'path'; export class PlaywrightGenerator { constructor(options = {}) { this.validateOptions(options); this.options = { ...PlaywrightGenerator.DEFAULT_OPTIONS, ...options }; } validateOptions(options) { if (options.outputPath && typeof options.outputPath !== 'string') { throw new Error('outputPath must be a string'); } if (options.testNamePrefix && typeof options.testNamePrefix !== 'string') { throw new Error('testNamePrefix must be a string'); } if (options.includeComments !== undefined && typeof options.includeComments !== 'boolean') { throw new Error('includeComments must be a boolean'); } } async generateTest(session) { if (!session || !Array.isArray(session.actions)) { throw new Error('Invalid session data'); } const testCase = this.createTestCase(session); const testCode = this.generateTestCode(testCase); const filePath = this.getOutputFilePath(session); return { testCode, filePath, sessionId: session.id, }; } createTestCase(session) { const testCase = { name: `${this.options.testNamePrefix}_${new Date(session.startTime).toISOString().split('T')[0]}`, steps: [], imports: new Set(['test', 'expect']), }; for (const action of session.actions) { const step = this.convertActionToStep(action); if (step) { testCase.steps.push(step); } } return testCase; } convertActionToStep(action) { const { toolName, parameters } = action; switch (toolName) { case 'playwright_navigate': return this.generateNavigateStep(parameters); case 'playwright_fill': return this.generateFillStep(parameters); case 'playwright_click': return this.generateClickStep(parameters); case 'playwright_screenshot': return this.generateScreenshotStep(parameters); case 'playwright_expect_response': return this.generateExpectResponseStep(parameters); case 'playwright_assert_response': return this.generateAssertResponseStep(parameters); case 'playwright_hover': return this.generateHoverStep(parameters); case 'playwright_select': return this.generateSelectStep(parameters); case 'playwright_custom_user_agent': return this.generateCustomUserAgentStep(parameters); default: console.warn(`Unsupported tool: ${toolName}`); return null; } } generateNavigateStep(parameters) { const { url, waitUntil } = parameters; const options = waitUntil ? `, { waitUntil: '${waitUntil}' }` : ''; return ` // Navigate to URL await page.goto('${url}'${options});`; } generateFillStep(parameters) { const { selector, value } = parameters; return ` // Fill input field await page.fill('${selector}', '${value}');`; } generateClickStep(parameters) { const { selector } = parameters; return ` // Click element await page.click('${selector}');`; } generateScreenshotStep(parameters) { const { name, fullPage = false, path } = parameters; const options = []; if (fullPage) options.push('fullPage: true'); if (path) options.push(`path: '${path}'`); const optionsStr = options.length > 0 ? `, { ${options.join(', ')} }` : ''; return ` // Take screenshot await page.screenshot({ path: '${name}.png'${optionsStr} });`; } generateExpectResponseStep(parameters) { const { url, id } = parameters; return ` // Wait for response const ${id}Response = page.waitForResponse('${url}');`; } generateAssertResponseStep(parameters) { const { id, value } = parameters; const assertion = value ? `\n const responseText = await ${id}Response.text();\n expect(responseText).toContain('${value}');` : `\n expect(${id}Response.ok()).toBeTruthy();`; return ` // Assert response${assertion}`; } generateHoverStep(parameters) { const { selector } = parameters; return ` // Hover over element await page.hover('${selector}');`; } generateSelectStep(parameters) { const { selector, value } = parameters; return ` // Select option await page.selectOption('${selector}', '${value}');`; } generateCustomUserAgentStep(parameters) { const { userAgent } = parameters; return ` // Set custom user agent await context.setUserAgent('${userAgent}');`; } generateTestCode(testCase) { const imports = Array.from(testCase.imports) .map(imp => `import { ${imp} } from '@playwright/test';`) .join('\n'); return ` ${imports} test('${testCase.name}', async ({ page, context }) => { ${testCase.steps.join('\n')} });`; } getOutputFilePath(session) { if (!session.id) { throw new Error('Session ID is required'); } const sanitizedPrefix = this.options.testNamePrefix.toLowerCase().replace(/[^a-z0-9_]/g, '_'); const fileName = `${sanitizedPrefix}_${session.id}.spec.ts`; return path.resolve(this.options.outputPath, fileName); } } PlaywrightGenerator.DEFAULT_OPTIONS = { outputPath: 'tests', testNamePrefix: 'MCP', includeComments: true, };