UNPKG

testeranto

Version:

the AI powered BDD test framework for typescript projects

230 lines (229 loc) 11.9 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.TestPage = void 0; /* eslint-disable @typescript-eslint/no-unused-vars */ const react_1 = __importStar(require("react")); const react_router_dom_1 = require("react-router-dom"); const api_1 = require("../../utils/api"); const TestPageView_1 = require("../pure/TestPageView"); const TestPage = () => { const navigate = (0, react_router_dom_1.useNavigate)(); const location = (0, react_router_dom_1.useLocation)(); const [route, setRoute] = (0, react_1.useState)('results'); // Sync route with hash changes (0, react_1.useEffect)(() => { const hash = location.hash.replace('#', ''); if (hash && ['results', 'logs', 'types', 'lint', 'coverage'].includes(hash)) { setRoute(hash); } else { setRoute('results'); } }, [location.hash]); const [testName, setTestName] = (0, react_1.useState)(''); // const [testData, setTestData] = useState(null); const [logs, setLogs] = (0, react_1.useState)({}); // const [typeErrors, setTypeErrors] = useState(''); // const [lintErrors, setLintErrors] = useState(''); const [loading, setLoading] = (0, react_1.useState)(true); const [error, setError] = (0, react_1.useState)(null); const [testsExist, setTestsExist] = (0, react_1.useState)(true); const [errorCounts, setErrorCounts] = (0, react_1.useState)({ typeErrors: 0, staticErrors: 0, runTimeErrors: 0 }); const [summary, setSummary] = (0, react_1.useState)(null); const { projectName, '*': splat } = (0, react_router_dom_1.useParams)(); const pathParts = splat ? splat.split('/') : []; const runtime = pathParts.pop() || ''; const testPath = pathParts.join('/'); const decodedTestPath = testPath ? decodeURIComponent(testPath) : ''; (0, react_1.useEffect)(() => { if (!projectName || !testPath || !runtime) return; setTestName(testPath); const fetchData = async () => { var _a; try { const [testResponse, metafileRes] = await Promise.all([ (0, api_1.fetchTestData)(projectName, testPath, runtime), fetch(`/metafiles/${runtime}/${projectName}.json`) ]); console.log('Fetching test data for:', { projectName, testPath, runtime }); const receivedLogs = await testResponse.logs; console.log('Received logs:', Object.keys(receivedLogs)); let sourceFiles = {}; if (metafileRes.ok) { const metafile = await metafileRes.json(); if ((_a = metafile === null || metafile === void 0 ? void 0 : metafile.metafile) === null || _a === void 0 ? void 0 : _a.outputs) { // Find input files only for this test's entry point const tsSources = new Set(); const testEntryPoint = `src/${testPath}`; // First find all outputs that match this test const matchingOutputs = Object.entries(metafile.metafile.outputs) .filter(([outputPath, output]) => { const normalizedTestPath = testPath.replace(/\./g, '_'); const testFileName = testPath.split('/').pop(); const testBaseName = testFileName === null || testFileName === void 0 ? void 0 : testFileName.split('.').slice(0, -1).join('.'); return output.entryPoint === testEntryPoint || outputPath.includes(normalizedTestPath) || (testBaseName && outputPath.includes(testBaseName)); }); // Then collect all inputs from matching outputs matchingOutputs.forEach(([_, output]) => { Object.keys(output.inputs).forEach(inputPath => { // Check if this input is a TypeScript file and not in node_modules if ((inputPath.endsWith('.ts') || inputPath.endsWith('.tsx')) && !inputPath.includes('node_modules')) { // Get the full input details from metafile.inputs const inputDetails = metafile.metafile.inputs[inputPath]; if (inputDetails) { tsSources.add(inputPath); // Also include any imported TypeScript files inputDetails.imports.forEach(imp => { if ((imp.path.endsWith('.ts') || imp.path.endsWith('.tsx')) && !imp.path.includes('node_modules') && !imp.external) { tsSources.add(imp.path); } }); } } }); }); // Organize source files into directory tree structure const fileTree = {}; const filesList = await Promise.all(Array.from(tsSources).map(async (filePath) => { try { const fetchPath = filePath.startsWith('/') ? filePath : `/${filePath.replace(/^\.\//, '')}`; const res = await fetch(fetchPath); if (res.ok) { return { path: filePath, content: await res.text() }; } return null; } catch (err) { console.warn(`Failed to fetch source file ${filePath}:`, err); return null; } })); filesList.forEach(file => { if (!file) return; const parts = file.path.split('/'); let currentLevel = fileTree; parts.forEach((part, index) => { if (!currentLevel[part]) { if (index === parts.length - 1) { currentLevel[part] = { __isFile: true, content: file.content }; } else { currentLevel[part] = {}; } } currentLevel = currentLevel[part]; }); }); sourceFiles = fileTree; } } // Add source files to logs receivedLogs['source_files'] = sourceFiles; console.log('Source files structure:', sourceFiles); // Ensure tests.json is properly formatted if (receivedLogs['tests.json']) { console.log('tests.json content type:', typeof receivedLogs['tests.json']); try { // Handle both string and already-parsed JSON if (typeof receivedLogs['tests.json'] === 'string') { receivedLogs['tests.json'] = JSON.parse(receivedLogs['tests.json']); } // If it's already an object, leave it as is } catch (e) { console.error('Failed to parse tests.json:', e); // Keep the original content but don't replace it with an error object } } setLogs(receivedLogs); // setTypeErrors(testResponse.typeErrors); // setLintErrors(testResponse.lintErrors); try { const summaryResponse = await fetch(`/reports/${projectName}/summary.json`); if (!summaryResponse.ok) throw new Error('Failed to fetch summary'); const allSummaries = await summaryResponse.json(); const testSummary = allSummaries[testPath]; if (testSummary) { const counts = { typeErrors: Number(testSummary.typeErrors) || 0, staticErrors: Number(testSummary.staticErrors) || 0, runTimeErrors: Number(testSummary.runTimeErrors) || 0 }; setSummary(testSummary); setErrorCounts(counts); setTestsExist(testSummary.testsExist !== false); } } catch (err) { console.error('Failed to load summary:', err); } } catch (err) { setError(err instanceof Error ? err.message : 'Unknown error'); setTestsExist(false); } finally { setLoading(false); } }; fetchData(); }, []); if (!logs) return react_1.default.createElement("div", null, "loading..."); return (react_1.default.createElement(react_1.default.Fragment, null, react_1.default.createElement(TestPageView_1.TestPageView, { route: route, setRoute: setRoute, navigate: navigate, projectName: projectName, testName: testName, decodedTestPath: decodedTestPath, runtime: runtime, logs: logs, testsExist: testsExist, errorCounts: errorCounts }))); }; exports.TestPage = TestPage;