UNPKG

testeranto

Version:

the AI powered BDD test framework for typescript projects

240 lines (239 loc) 9.34 kB
/* eslint-disable @typescript-eslint/ban-ts-comment */ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-unused-vars */ import { WebSocketServer } from "ws"; import http from "http"; import fs from "fs"; import { getAllFilesRecursively } from "./getAllFilesRecursively.js"; import { FileService_methods } from "../FileService.js"; import { ApiEndpoint, ApiFilename } from "../api.js"; import { PM_1_WithProcesses } from "./PM_1_WithProcesses.js"; export class PM_2_WithTCP extends PM_1_WithProcesses { constructor(configs, name, mode) { super(configs, name, mode); console.log("mark2", this.configs); console.log("mark3", configs); this.httpServer = http.createServer(this.handleHttpRequest.bind(this)); this.wss = new WebSocketServer({ server: this.httpServer }); this.wss.on("connection", (ws) => { this.clients.add(ws); console.log("Client connected"); ws.on("message", (data) => { try { this.websocket(data, ws); } catch (error) { console.error("Error handling WebSocket message:", error); } }); ws.on("close", () => { this.clients.delete(ws); console.log("Client disconnected"); }); ws.on("error", (error) => { console.error("WebSocket error:", error); this.clients.delete(ws); }); }); const httpPort = Number(process.env.HTTP_PORT) || 3000; this.httpServer.listen(httpPort, "0.0.0.0", () => { console.log(`HTTP server running on http://localhost:${httpPort}`); }); } websocket(data, ws) { try { const wsm = JSON.parse(data.toString()); FileService_methods.forEach((fsm) => { if (wsm.type === fsm) { this[fsm](wsm, ws); } }); // Handle other message types if (wsm.type === "getRunningProcesses") { const processes = Array.from(this.allProcesses.entries()).map(([id, procInfo]) => ({ processId: id, command: procInfo.command, pid: procInfo.pid, status: procInfo.status, exitCode: procInfo.exitCode, error: procInfo.error, timestamp: procInfo.timestamp, category: procInfo.category, testName: procInfo.testName, platform: procInfo.platform, logs: this.processLogs.get(id) || [], })); ws.send(JSON.stringify({ type: "runningProcesses", processes, })); } else if (wsm.type === "getProcess") { const processId = wsm.data.processId; const procInfo = this.allProcesses.get(processId); if (procInfo) { ws.send(JSON.stringify({ type: "processData", processId, command: procInfo.command, pid: procInfo.pid, status: procInfo.status, exitCode: procInfo.exitCode, error: procInfo.error, timestamp: procInfo.timestamp, category: procInfo.category, testName: procInfo.testName, platform: procInfo.platform, logs: this.processLogs.get(processId) || [], })); } } else if (wsm.type === "stdin") { const processId = wsm.data.processId; const data = wsm.data.data; const childProcess = this.runningProcesses.get(processId); if (childProcess && childProcess.stdin) { childProcess.stdin.write(data); } else { console.log("Cannot write to stdin - process not found or no stdin:", { processExists: !!childProcess, stdinExists: (childProcess === null || childProcess === void 0 ? void 0 : childProcess.stdin) ? true : false, }); } } else if (wsm.type === "killProcess") { const processId = wsm.processId; console.log("Received killProcess for process", processId); const childProcess = this.runningProcesses.get(processId); if (childProcess) { console.log("Killing process"); childProcess.kill("SIGTERM"); } else { console.log("Cannot kill process - process not found:", { processExists: !!childProcess, }); } } else if (wsm.type === "getChatHistory") { if (this.getChatHistory) { this .getChatHistory() .then((history) => { ws.send(JSON.stringify({ type: "chatHistory", messages: history, })); }) .catch((error) => { console.error("Error getting chat history:", error); ws.send(JSON.stringify({ type: "error", message: "Failed to get chat history", })); }); } } } catch (error) { console.error("Error handling WebSocket message:", error); } } handleHttpRequest(req, res) { console.log(req.method, req.url); if (req.url === ApiEndpoint.root) { fs.readFile(ApiFilename.root, (err, data) => { if (err) { res.writeHead(404, { "Content-Type": "text/plain" }); res.end(`500 ${err.toString()}`); return; } res.writeHead(200, { "Content-Type": "text/html" }); res.end(data); }); return; } else if (req.url === ApiEndpoint.style) { fs.readFile(ApiFilename.style, (err, data) => { if (err) { res.writeHead(404, { "Content-Type": "text/plain" }); res.end(`500 ${err.toString()}`); return; } res.writeHead(200, { "Content-Type": "text/css" }); res.end(data); }); return; } else if (req.url === ApiEndpoint.script) { fs.readFile(ApiFilename.script, (err, data) => { if (err) { res.writeHead(404, { "Content-Type": "text/plain" }); res.end(`500 ${err.toString()}`); return; } res.writeHead(200, { "Content-Type": "text/css" }); res.end(data); return; }); return; } else { res.writeHead(404); res.end(`404 Not Found. ${req.url}`); return; } } // FileService methods writeFile_send(wsm, ws) { ws.send(JSON.stringify(["writeFile", wsm.data.path])); } writeFile_receive(wsm, ws) { fs.writeFileSync(wsm.data.path, wsm.data.content); } readFile_receive(wsm, ws) { this.readFile_send(wsm, ws, fs.readFileSync(wsm.data.path).toString()); } readFile_send(wsm, ws, content) { ws.send(JSON.stringify(["readFile", wsm.data.path, content])); } createDirectory_receive(wsm, ws) { fs.mkdirSync(wsm.data.path); this.createDirectory_send(wsm, ws); } createDirectory_send(wsm, ws) { ws.send(JSON.stringify(["createDirectory", wsm.data.path])); } deleteFile_receive(wsm, ws) { fs.unlinkSync(wsm.data.path); this.deleteFile_send(wsm, ws); } deleteFile_send(wsm, ws) { ws.send(JSON.stringify(["deleteFile", wsm.data.path])); } async files_receive(wsm, ws) { this.files_send(wsm, ws, await getAllFilesRecursively(".")); } files_send(wsm, ws, files) { ws.send(JSON.stringify(["files", files])); } projects_receive(wsm, ws) { this.projects_send(wsm, ws, JSON.parse(fs.readFileSync("./testeranto/projects.json", "utf-8"))); } projects_send(wsm, ws, projects) { ws.send(JSON.stringify(["projects", projects])); } report_receive(wsm, ws) { this.report_send(wsm, ws); } async report_send(wsm, ws) { // Implementation remains the same } async test_receive(wsm, ws) { // Implementation remains the same } test_send(wsm, ws, project) { ws.send(JSON.stringify(["tests", project])); } }