@empiricalrun/test-gen 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @empiricalrun/test-gen
2
2
 
3
+ ## 0.1.3
4
+
5
+ ### Patch Changes
6
+
7
+ - b32c561: fix: increase readability of logs
8
+
3
9
  ## 0.1.2
4
10
 
5
11
  ### Patch Changes
package/dist/bin/index.js CHANGED
@@ -13,9 +13,11 @@ const prettier_1 = __importDefault(require("prettier"));
13
13
  const eslint_1 = require("eslint");
14
14
  const dotenv_1 = __importDefault(require("dotenv"));
15
15
  const yaml_1 = require("yaml");
16
+ const logger_1 = require("./logger");
16
17
  dotenv_1.default.config({
17
18
  path: [".env.local", ".env"],
18
19
  });
20
+ const logger = new logger_1.CustomLogger();
19
21
  async function readFilesInDirectory(dir = "") {
20
22
  let files = [];
21
23
  const items = await fs_extra_1.default.readdir(dir);
@@ -67,7 +69,6 @@ async function getLLMResult(instruction) {
67
69
  ],
68
70
  model: "gpt-4o",
69
71
  });
70
- console.log("generated completion");
71
72
  const response = completion.choices[0]?.message.content || "";
72
73
  return response;
73
74
  }
@@ -83,32 +84,24 @@ function validateTypescript(filePath) {
83
84
  const errors = [];
84
85
  const syntacticDiagnostics = program.getSyntacticDiagnostics(sourceFile);
85
86
  if (syntacticDiagnostics.length > 0) {
86
- console.log("Syntactic errors:");
87
87
  syntacticDiagnostics.forEach((diagnostic) => {
88
88
  const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
89
89
  const message = typescript_1.default.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
90
- console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
90
+ logger.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
91
91
  if (typeof diagnostic.messageText === "string") {
92
92
  errors.push(diagnostic.messageText);
93
93
  }
94
94
  });
95
95
  }
96
- else {
97
- console.log("No syntactic errors.");
98
- }
99
96
  // Get and report any semantic errors
100
97
  const semanticDiagnostics = program.getSemanticDiagnostics(sourceFile);
101
98
  if (semanticDiagnostics.length > 0) {
102
- console.log("Semantic errors:");
103
99
  semanticDiagnostics.forEach((diagnostic) => {
104
- console.log(diagnostic.messageText);
105
- if (typeof diagnostic.messageText == "string") {
106
- errors.push(diagnostic.messageText);
107
- }
100
+ errors.push(diagnostic.messageText.toString());
108
101
  });
109
102
  }
110
- else {
111
- console.log("No semantic errors.");
103
+ if (!errors.length) {
104
+ logger.success("Found no type issues!");
112
105
  }
113
106
  return errors;
114
107
  }
@@ -120,7 +113,7 @@ async function formatCode(filePath) {
120
113
  filepath: filePath,
121
114
  });
122
115
  fs_extra_1.default.writeFileSync(filePath, formattedContent);
123
- console.log("File formatted successfully.");
116
+ logger.success("File formatted successfully!");
124
117
  }
125
118
  async function stripAndPrependImports(content) {
126
119
  const imports = content.match(/import.* from.*;/g);
@@ -141,12 +134,12 @@ async function generateTest(scenarios, file) {
141
134
  const pomPrompt = await generatePromptFromDirectory("./pages");
142
135
  const testFileContent = fs_extra_1.default.readFileSync(file, "utf-8");
143
136
  for (const i in scenarios) {
137
+ console.log("\n\n");
144
138
  const scenario = scenarios[i];
145
- console.log("Generating test for scenario: ", scenario?.name);
139
+ logger.log("Generating test for scenario:", scenario?.name);
146
140
  //TODO: improve this logic. its buggy
147
141
  if (testFileContent.includes(`test("${scenario?.name}"`)) {
148
- console.log("test already exists for this scenario", scenario?.name);
149
- console.log("skipping test generation");
142
+ logger.success("Test already exists for this scenario");
150
143
  continue;
151
144
  }
152
145
  const instruction = `
@@ -183,25 +176,27 @@ async function generateTest(scenarios, file) {
183
176
  - Donot repeat steps which are already mentioned in the "test.beforeEach" block
184
177
  - Add import statements at the beginning of the output.
185
178
  `;
186
- console.log("constructed instruction for llm");
187
179
  let response = await getLLMResult(instruction);
180
+ logger.success("Test generated successfully!");
188
181
  const contents = fs_extra_1.default.readFileSync(file, "utf-8");
189
182
  const [prependContent, strippedContent] = await stripAndPrependImports(response);
190
183
  await fs_extra_1.default.writeFile(file, prependContent + contents + `\n\n${strippedContent}`, "utf-8");
191
- console.log("Linting generated output");
184
+ logger.log("Linting generated code...");
192
185
  await lintErrors(file);
193
- console.log("Validating types");
186
+ logger.log("Validating types...");
194
187
  let errors = validateTypescript(file);
195
188
  const maxIteration = 2;
196
189
  let counter = 0;
197
190
  while (errors.length > 0) {
198
- console.log(errors);
199
191
  const fileContent = fs_extra_1.default.readFileSync(file, "utf-8");
200
192
  counter += 1;
201
193
  if (counter > maxIteration) {
202
- console.log(`Max iteration limit reached. Please review the file ${file} and manually fix the typescript errors.`);
194
+ logger.error(`Unable to fix typescript errors. Please review ${file} manually and fix the typescript errors. Run the test-gen command again, once errors are fixed`);
203
195
  break;
204
196
  }
197
+ logger.warn("Found few errors while validating types:");
198
+ errors.forEach(e => logger.warn(e));
199
+ logger.log("Trying to fix above errors...");
205
200
  const instruction = `
206
201
  You are a software engineer who is given a task to create test basis a scenario provided to you.
207
202
  You will be provided with current tests, fixtures and page object models for you to use and write test.
@@ -230,18 +225,16 @@ async function generateTest(scenarios, file) {
230
225
  - Donot modify anything else apart from the code required to fix typescript error
231
226
  `;
232
227
  response = await getLLMResult(instruction);
233
- console.log("fixed");
234
- console.log(response);
235
- errors = validateTypescript(file);
236
228
  await fs_extra_1.default.writeFile(file, response, "utf-8");
229
+ await lintErrors(file);
230
+ errors = validateTypescript(file);
237
231
  }
238
- console.log("formatting spec file");
239
232
  await formatCode(file);
240
233
  }
241
234
  }
242
235
  (async function main() {
243
236
  if (process.argv.length != 3) {
244
- console.log("Provide a path to scenarios path to generate test");
237
+ logger.error("Please provide path to scenarios using command:", "npx @empiricalrun/test-gen <SCENARIOS_FILE_PATH>");
245
238
  process.exit(1);
246
239
  }
247
240
  else {
@@ -252,11 +245,8 @@ async function generateTest(scenarios, file) {
252
245
  const scenarios = config.scenarios;
253
246
  const fileDir = config.dir || "./tests";
254
247
  const filePath = `${fileDir}/${fileName}.spec.ts`;
255
- if (fs_extra_1.default.existsSync(filePath)) {
256
- console.log("Spec file already exists, skipping generation");
257
- }
258
- else {
259
- console.log("Spec file does not exist, creating new spec file");
248
+ if (!fs_extra_1.default.existsSync(filePath)) {
249
+ logger.log(`Creating a new spec file: ${filePath}`);
260
250
  fs_extra_1.default.createFileSync(filePath);
261
251
  }
262
252
  await generateTest(scenarios, filePath);
@@ -0,0 +1,13 @@
1
+ export interface Logger {
2
+ log: (message?: string, ...optionalParams: any[]) => void;
3
+ warn: (message?: string, ...optionalParams: any[]) => void;
4
+ error: (message?: string, ...optionalParams: any[]) => void;
5
+ success: (message?: string, ...optionalParams: any[]) => void;
6
+ }
7
+ export declare class CustomLogger implements Logger {
8
+ log(message?: string, ...optionalParams: any[]): void;
9
+ warn(message?: string, ...optionalParams: any[]): void;
10
+ success(message?: string, ...optionalParams: any[]): void;
11
+ error(message?: string, ...optionalParams: any[]): void;
12
+ }
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bin/logger/index.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IAC1D,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IAC3D,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IAC5D,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;CAC/D;AAED,qBAAa,YAAa,YAAW,MAAM;IACzC,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAI9C,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAI/C,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAIlD,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;CAGjD"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CustomLogger = void 0;
4
+ const picocolors_1 = require("picocolors");
5
+ class CustomLogger {
6
+ log(message, ...optionalParams) {
7
+ console.log("🪵 ", (0, picocolors_1.cyan)(message), ...optionalParams);
8
+ }
9
+ warn(message, ...optionalParams) {
10
+ console.log("🟡 ", (0, picocolors_1.yellow)(message), ...optionalParams);
11
+ }
12
+ success(message, ...optionalParams) {
13
+ console.log("✅", (0, picocolors_1.green)(message), ...optionalParams);
14
+ }
15
+ error(message, ...optionalParams) {
16
+ console.log("🚨", (0, picocolors_1.red)(message), ...optionalParams);
17
+ }
18
+ }
19
+ exports.CustomLogger = CustomLogger;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empiricalrun/test-gen",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"
@@ -19,6 +19,7 @@
19
19
  "eslint": "^8.57.0",
20
20
  "fs-extra": "^11.2.0",
21
21
  "openai": "^4.47.2",
22
+ "picocolors": "^1.0.1",
22
23
  "prettier": "^3.2.5",
23
24
  "typescript": "^5.3.3",
24
25
  "yaml": "^2.4.2"