@competent-devs/test-forge
Version:
Package for UI unit test generation based on storybook context
69 lines (67 loc) • 2.7 kB
JavaScript
import * as path from "node:path";
import * as fs from "node:fs/promises";
import mustache from "mustache";
import { fileURLToPath } from "url";
import { extractSource } from "storybook/internal/csf-tools";
import { invokeLlmChain } from "./agent.js";
import { logToFile } from "./logger.js";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const getPromptTemplate = async () => {
return await fs.readFile(path.join(__dirname, "./prompt.mustache"), "utf8");
};
const regeneratePromptTemplate = async () => {
return await fs.readFile(path.join(__dirname, "./prompt-regenerate.mustache"), "utf8");
};
export async function generateTests(storyPath, csfFile, fileContent) {
const parsedFilePath = path.parse(storyPath);
console.log(storyPath, parsedFilePath, parsedFilePath.name);
let code = `
import { test, expect } from 'vitest'
import { screen, within } from '@testing-library/react'
import { composeStories } from '@storybook/react'
import * as stories from './${parsedFilePath.name}'
const { ${csfFile.indexInputs.map((indexInput) => indexInput.exportName).join(", ")} } = composeStories(stories)
`;
for (const indexInput of csfFile.indexInputs) {
if (indexInput.type !== "story") {
continue;
}
code += `
test('${indexInput.name}', async () => {
await ${indexInput.exportName}.run()
`;
code = await autocompleteTest(code, indexInput, csfFile, fileContent);
}
return code;
}
export async function autocompleteTest(code, indexInput, csfFile, fileContent) {
const storyExportName = indexInput.exportName;
const storySource = extractSource(csfFile.getStoryExport(storyExportName));
const PROMPT_TEMPLATE = await getPromptTemplate();
const response = await invokeLlmChain(mustache.render(PROMPT_TEMPLATE, {
code,
storyExportName,
storySource,
fileContent,
}));
code += response?.response || "\n})" + "\n";
logToFile(code);
return code;
}
export async function regenerateTestsWithErrors(code, errorDetails) {
console.log("Regenerating test with errors...");
const REGENERATE_PROMPT_TEMPLATE = await regeneratePromptTemplate();
const messages = mustache.render(REGENERATE_PROMPT_TEMPLATE, {
code,
errorDetails,
});
console.log(messages);
logToFile("LLM Prompt for Regeneration");
logToFile(JSON.stringify(messages));
const response = await invokeLlmChain(messages);
console.log("Response after regenerating from LLM Chain:");
console.log(response);
return response?.response;
}
//# sourceMappingURL=generate-tests.js.map