UNPKG

testeranto

Version:

the AI powered BDD test framework for typescript projects

204 lines (203 loc) 7.51 kB
/* eslint-disable @typescript-eslint/no-unused-vars */ import ansiC from "ansi-colors"; import path from "path"; import fs from "fs"; import crypto from "node:crypto"; export function runtimeLogs(runtime, reportDest) { const safeDest = reportDest || `testeranto/reports/default_${Date.now()}`; try { if (!fs.existsSync(safeDest)) { fs.mkdirSync(safeDest, { recursive: true }); } if (runtime === "node") { return { stdout: fs.createWriteStream(`${safeDest}/stdout.log`), stderr: fs.createWriteStream(`${safeDest}/stderr.log`), exit: fs.createWriteStream(`${safeDest}/exit.log`), }; } else if (runtime === "web") { return { info: fs.createWriteStream(`${safeDest}/info.log`), warn: fs.createWriteStream(`${safeDest}/warn.log`), error: fs.createWriteStream(`${safeDest}/error.log`), debug: fs.createWriteStream(`${safeDest}/debug.log`), exit: fs.createWriteStream(`${safeDest}/exit.log`), }; } else if (runtime === "pure") { return { exit: fs.createWriteStream(`${safeDest}/exit.log`), }; } else if (runtime === "python") { return { stdout: fs.createWriteStream(`${safeDest}/stdout.log`), stderr: fs.createWriteStream(`${safeDest}/stderr.log`), exit: fs.createWriteStream(`${safeDest}/exit.log`), }; } else if (runtime === "golang") { return { stdout: fs.createWriteStream(`${safeDest}/stdout.log`), stderr: fs.createWriteStream(`${safeDest}/stderr.log`), exit: fs.createWriteStream(`${safeDest}/exit.log`), }; } else { throw `unknown runtime: ${runtime}`; } } catch (e) { console.error(`Failed to create log streams in ${safeDest}:`, e); throw e; } } export function createLogStreams(reportDest, runtime) { // Create directory if it doesn't exist if (!fs.existsSync(reportDest)) { fs.mkdirSync(reportDest, { recursive: true }); } // const streams = { // exit: fs.createWriteStream(`${reportDest}/exit.log`), const safeDest = reportDest || `testeranto/reports/default_${Date.now()}`; try { if (!fs.existsSync(safeDest)) { fs.mkdirSync(safeDest, { recursive: true }); } const streams = runtimeLogs(runtime, safeDest); // const streams = { // exit: fs.createWriteStream(`${safeDest}/exit.log`), // ...(runtime === "node" || runtime === "pure" // ? { // stdout: fs.createWriteStream(`${safeDest}/stdout.log`), // stderr: fs.createWriteStream(`${safeDest}/stderr.log`), // } // : { // info: fs.createWriteStream(`${safeDest}/info.log`), // warn: fs.createWriteStream(`${safeDest}/warn.log`), // error: fs.createWriteStream(`${safeDest}/error.log`), // debug: fs.createWriteStream(`${safeDest}/debug.log`), // }), // }; return Object.assign(Object.assign({}, streams), { closeAll: () => { Object.values(streams).forEach((stream) => !stream.closed && stream.close()); }, writeExitCode: (code, error) => { if (error) { streams.exit.write(`Error: ${error.message}\n`); if (error.stack) { streams.exit.write(`Stack Trace:\n${error.stack}\n`); } } streams.exit.write(`${code}\n`); }, exit: streams.exit }); } catch (e) { console.error(`Failed to create log streams in ${safeDest}:`, e); throw e; } } export async function fileHash(filePath, algorithm = "md5") { return new Promise((resolve, reject) => { const hash = crypto.createHash(algorithm); const fileStream = fs.createReadStream(filePath); fileStream.on("data", (data) => { hash.update(data); }); fileStream.on("end", () => { const fileHash = hash.digest("hex"); resolve(fileHash); }); fileStream.on("error", (error) => { reject(`Error reading file: ${error.message}`); }); }); } export const statusMessagePretty = (failures, test, runtime) => { if (failures === 0) { console.log(ansiC.green(ansiC.inverse(`${runtime} > ${test}`))); } else if (failures > 0) { console.log(ansiC.red(ansiC.inverse(`${runtime} > ${test} failed ${failures} times (exit code: ${failures})`))); } else { console.log(ansiC.red(ansiC.inverse(`${runtime} > ${test} crashed (exit code: -1)`))); } }; export async function writeFileAndCreateDir(filePath, data) { const dirPath = path.dirname(filePath); try { await fs.promises.mkdir(dirPath, { recursive: true }); await fs.writeFileSync(filePath, data); } catch (error) { console.error(`Error writing file: ${error}`); } } export const filesHash = async (files, algorithm = "md5") => { return new Promise((resolve, reject) => { resolve(files.reduce(async (mm, f) => { return (await mm) + (await fileHash(f)); }, Promise.resolve(""))); }); }; export function isValidUrl(string) { try { new URL(string); return true; } catch (err) { return false; } } // Wait for file to exist, checks every 2 seconds by default export async function pollForFile(path, timeout = 2000) { const intervalObj = setInterval(function () { const file = path; const fileExists = fs.existsSync(file); if (fileExists) { clearInterval(intervalObj); } }, timeout); } const executablePath = "/opt/homebrew/bin/chromium"; export const puppeteerConfigs = { slowMo: 1, waitForInitialPage: false, executablePath, headless: true, defaultViewport: null, // Disable default 800x600 viewport dumpio: false, devtools: false, args: [ "--allow-file-access-from-files", "--allow-insecure-localhost", "--allow-running-insecure-content", "--auto-open-devtools-for-tabs", "--disable-dev-shm-usage", "--disable-extensions", "--disable-features=site-per-process", "--disable-gpu", "--disable-setuid-sandbox", "--disable-site-isolation-trials", "--disable-web-security", "--no-first-run", "--no-sandbox", "--no-startup-window", "--reduce-security-for-testing", "--remote-allow-origins=*", "--start-maximized", "--unsafely-treat-insecure-origin-as-secure=*", `--remote-debugging-port=3234`, // "--disable-features=IsolateOrigins,site-per-process", // "--disable-features=IsolateOrigins", // "--disk-cache-dir=/dev/null", // "--disk-cache-size=1", // "--no-zygote", // "--remote-allow-origins=ws://localhost:3234", // "--single-process", // "--start-maximized", // "--unsafely-treat-insecure-origin-as-secure", // "--unsafely-treat-insecure-origin-as-secure=ws://192.168.0.101:3234", ], };