import { z } from 'zod'; import { config } from '../../config.js'; import { detectJsPackageManager, runScriptCommandFor } from '../../lib/frameworks/packageManager.js'; import { runCommand } from '../../lib/runCommand.js'; import { errorResult, jsonResult, toErrorMessage } from '../shared.js'; import { requireReact } from './requireReact.js'; function parseReactTestingLibraryOutput(output) { // Extract failing test names and common RTL errors for a quick summary. const failingTests = output .split(/\n(?=\s*FAIL|●)/) .filter((chunk) => chunk.includes('●')) .map((chunk) => { const match = chunk.match(/●\s*(.+?)(?:\n|$)/); return match?.[1]?.trim() ?? null; }) .filter((item) => Boolean(item)); const rtlErrors = []; if (/Unable to find an element/i.test(output)) rtlErrors.push('Unable to find an element (getBy/queryBy failed)'); if (/Found multiple elements/i.test(output)) rtlErrors.push('Found multiple elements with the same query'); if (/found accessibility element/i.test(output)) rtlErrors.push('Role/name based query mismatch'); if (/Timed out in waitFor/i.test(output)) rtlErrors.push('waitFor timeout (async assertion not satisfied)'); if (/Warning: An update to .* inside a test was not wrapped in act/i.test(output)) { rtlErrors.push('Missing act() wrapper around state update'); } const totalMatch = output.match(/Tests\s+(\d+)\s+passed/i) || output.match(/Test Suites?:\s*(\d+)\s+passed/i); return { failingTestCount: failingTests.length, failingTests: failingTests.slice(0, 10), rtlErrors: rtlErrors.slice(0, 10), testsPassed: totalMatch ? Number(totalMatch[1]) : null, }; } export function registerRunReactTestsTool(server) { server.registerTool('run_react_tests', { title: 'Run React Tests', description: 'Run the React test runner (Jest/Vitest + React Testing Library) via package.json "test" script and surface RTL-specific failures.', inputSchema: { extraArgs: z .array(z.string()) .optional() .describe('Extra CLI args, e.g. ["--filter", "UserCard"].'), }, }, async ({ extraArgs }) => { try { const react = requireReact(); const pm = detectJsPackageManager(react.root); const { command, args } = runScriptCommandFor(pm, 'test', extraArgs ?? []); const result = await runCommand(command, args, { cwd: react.root, timeoutMs: config.scaffoldCommandTimeoutMs, }); return jsonResult({ runner: 'npm-test-script', summary: parseReactTestingLibraryOutput(result.output), ...result, }); } catch (error) { return errorResult(toErrorMessage(error)); } }); } //# sourceMappingURL=runReactTests.js.map