@empiricalrun/test-gen 0.68.0 → 0.69.1

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.
Files changed (50) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/agent/chat/exports.d.ts +8 -8
  3. package/dist/agent/chat/exports.d.ts.map +1 -1
  4. package/dist/agent/chat/exports.js +10 -7
  5. package/dist/agent/chat/index.d.ts.map +1 -1
  6. package/dist/agent/chat/index.js +5 -2
  7. package/dist/agent/chat/state.d.ts +4 -2
  8. package/dist/agent/chat/state.d.ts.map +1 -1
  9. package/dist/agent/chat/state.js +10 -2
  10. package/dist/agent/chat/utils.d.ts +5 -1
  11. package/dist/agent/chat/utils.d.ts.map +1 -1
  12. package/dist/agent/chat/utils.js +22 -0
  13. package/dist/agent/cua/pw-codegen/pw-pause/for-recorder.d.ts.map +1 -1
  14. package/dist/agent/cua/pw-codegen/pw-pause/for-recorder.js +24 -3
  15. package/dist/agent/cua/pw-codegen/pw-pause/index.d.ts.map +1 -1
  16. package/dist/agent/cua/pw-codegen/pw-pause/index.js +5 -4
  17. package/dist/agent/cua/pw-codegen/pw-pause/patch.d.ts.map +1 -1
  18. package/dist/agent/cua/pw-codegen/pw-pause/patch.js +4 -6
  19. package/dist/auth/api-client.d.ts +1 -1
  20. package/dist/auth/api-client.d.ts.map +1 -1
  21. package/dist/auth/api-client.js +3 -2
  22. package/dist/auth/cli-auth.js +1 -1
  23. package/dist/bin/index.js +10 -2
  24. package/dist/bin/setup.d.ts +4 -0
  25. package/dist/bin/setup.d.ts.map +1 -0
  26. package/dist/bin/setup.js +86 -0
  27. package/dist/bin/utils/index.d.ts +1 -0
  28. package/dist/bin/utils/index.d.ts.map +1 -1
  29. package/dist/bin/utils/index.js +1 -1
  30. package/dist/file/server.d.ts.map +1 -1
  31. package/dist/file/server.js +60 -1
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +3 -2
  34. package/dist/logger.d.ts +3 -0
  35. package/dist/logger.d.ts.map +1 -0
  36. package/dist/logger.js +11 -0
  37. package/dist/recorder/index.d.ts.map +1 -1
  38. package/dist/recorder/index.js +31 -11
  39. package/dist/recorder/request.d.ts.map +1 -1
  40. package/dist/recorder/request.js +158 -8
  41. package/dist/recorder/temp-files.d.ts +1 -1
  42. package/dist/recorder/temp-files.d.ts.map +1 -1
  43. package/dist/recorder/temp-files.js +7 -7
  44. package/dist/recorder/upload.d.ts.map +1 -1
  45. package/dist/recorder/upload.js +0 -1
  46. package/package.json +6 -4
  47. package/tsconfig.tsbuildinfo +1 -1
  48. package/dist/recorder/display.d.ts +0 -2
  49. package/dist/recorder/display.d.ts.map +0 -1
  50. package/dist/recorder/display.js +0 -50
@@ -42,10 +42,69 @@ class FileServiceServer {
42
42
  const app = (0, express_1.default)();
43
43
  app.use(express_1.default.json({ limit: "50mb" }));
44
44
  (0, ipc_1.humanLoopRoute)(app);
45
+ app.get("/ready", (req, res) => {
46
+ const html = `
47
+ <!DOCTYPE html>
48
+ <html>
49
+ <head>
50
+ <title>Record</title>
51
+ <style>
52
+ body {
53
+ display: flex;
54
+ justify-content: center;
55
+ align-items: center;
56
+ height: 100vh;
57
+ margin: 0;
58
+ font-family: sans-serif;
59
+ font-size: 24px;
60
+ }
61
+ .message {
62
+ opacity: 0;
63
+ animation: fadeIn 0.5s ease-in forwards;
64
+ }
65
+ .pulsate {
66
+ animation: pulsate 1s ease-in-out infinite;
67
+ }
68
+ @keyframes fadeIn {
69
+ to {
70
+ opacity: 1;
71
+ }
72
+ }
73
+ @keyframes pulsate {
74
+ 0%, 100% {
75
+ opacity: 1;
76
+ }
77
+ 50% {
78
+ opacity: 0.6;
79
+ }
80
+ }
81
+ </style>
82
+ </head>
83
+ <body>
84
+ <div class="message pulsate" id="message">Getting ready to record</div>
85
+ <script>
86
+ setTimeout(() => {
87
+ const message = document.getElementById('message');
88
+ message.className = 'message';
89
+ message.style.opacity = '0';
90
+ setTimeout(() => {
91
+ message.textContent = 'Ready to record';
92
+ message.style.opacity = '1';
93
+ }, 300);
94
+ }, 2000);
95
+ </script>
96
+ </body>
97
+ </html>
98
+ `;
99
+ res.send(html);
100
+ });
45
101
  app.post("/codegen-sources", async (req) => {
46
102
  const payload = req.body;
47
103
  this.codegenSources = payload.map((c) => c.actions.join("\n")).join("\n");
48
- console.log("[FileServiceServer] Received codegen sources", this.codegenSources);
104
+ // console.log(
105
+ // "[FileServiceServer] Received codegen sources",
106
+ // this.codegenSources,
107
+ // );
49
108
  });
50
109
  app.post("/agent-results", async (req, res) => {
51
110
  const { generatedCode, importPaths, result, usage } = req.body;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAahD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAsB7C,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,IAAI,GAAG,YAAY,EAC5B,KAAK,CAAC,EAAE,SAAS,iBAwElB;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,IAAI,iBAY7C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAchD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAsB7C,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,IAAI,GAAG,YAAY,EAC5B,KAAK,CAAC,EAAE,SAAS,iBAwElB;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,IAAI,iBAY7C"}
package/dist/index.js CHANGED
@@ -13,6 +13,7 @@ const for_recorder_1 = require("./agent/cua/pw-codegen/pw-pause/for-recorder");
13
13
  const run_1 = require("./agent/master/run");
14
14
  const scenarios_1 = require("./bin/utils/scenarios");
15
15
  const client_1 = __importDefault(require("./file/client"));
16
+ const logger_1 = require("./logger");
16
17
  const reporter_1 = require("./reporter");
17
18
  const session_1 = require("./session");
18
19
  var test_build_1 = require("./test-build");
@@ -102,9 +103,9 @@ async function recordTest(pageRef) {
102
103
  const repoDir = process.cwd();
103
104
  const canUsePwPause = await (0, pw_pause_1.canUsePauseCodegen)(repoDir);
104
105
  if (!canUsePwPause) {
105
- return;
106
+ throw new Error("Unable to start recording: please report this issue.");
106
107
  }
107
- console.log("[getCodegen] using PlaywrightPauseCodegen");
108
+ logger_1.logger.debug("[getCodegen] using PlaywrightPauseCodegen");
108
109
  const codegen = new for_recorder_1.PlaywrightPauseCodegenForRecorder(async (sources) => {
109
110
  await fileServiceClient.sendCodegenSources(sources);
110
111
  });
@@ -0,0 +1,3 @@
1
+ import Logger from "console-log-level";
2
+ export declare const logger: Logger.Logger;
3
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,MAAyB,MAAM,mBAAmB,CAAC;AAE1D,eAAO,MAAM,MAAM,eAGjB,CAAC"}
package/dist/logger.js ADDED
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.logger = void 0;
7
+ const console_log_level_1 = __importDefault(require("console-log-level"));
8
+ exports.logger = (0, console_log_level_1.default)({
9
+ prefix: "test-gen",
10
+ level: process.env.LOG_LEVEL || "info",
11
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/recorder/index.ts"],"names":[],"mappings":"AAiBA,wBAAsB,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,iBA2E3D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/recorder/index.ts"],"names":[],"mappings":"AAkBA,wBAAsB,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,iBAgG3D"}
@@ -9,8 +9,9 @@ const detect_port_1 = __importDefault(require("detect-port"));
9
9
  const path_1 = __importDefault(require("path"));
10
10
  const utils_1 = require("../agent/browsing/utils");
11
11
  const pw_pause_1 = require("../agent/cua/pw-codegen/pw-pause");
12
+ const api_client_1 = require("../auth/api-client");
12
13
  const server_1 = require("../file/server");
13
- const display_1 = require("./display");
14
+ const logger_1 = require("../logger");
14
15
  const env_variables_1 = require("./env-variables");
15
16
  const request_1 = require("./request");
16
17
  const temp_files_1 = require("./temp-files");
@@ -18,8 +19,29 @@ const upload_1 = require("./upload");
18
19
  const validation_1 = require("./validation");
19
20
  async function runRecorder({ name }) {
20
21
  console.log(`Recording for test name: ${name}`);
22
+ try {
23
+ await api_client_1.apiClient.ensureAuthenticated();
24
+ }
25
+ catch (error) {
26
+ console.error("Authentication required: please run @empiricalrun/test-gen login first");
27
+ process.exit(1);
28
+ }
21
29
  const repoDir = process.cwd();
22
30
  let repoName = "";
31
+ let fileServer = null;
32
+ process.on("SIGINT", async () => {
33
+ try {
34
+ await (0, temp_files_1.deleteTempTestFile)();
35
+ await (0, pw_pause_1.revertToOriginalPwCode)(repoDir);
36
+ if (fileServer) {
37
+ await fileServer.stop();
38
+ }
39
+ }
40
+ catch (error) {
41
+ console.error("Error during cleanup:", error);
42
+ }
43
+ process.exit(0);
44
+ });
23
45
  try {
24
46
  repoName = await (0, validation_1.validatePackageJson)(repoDir);
25
47
  }
@@ -28,25 +50,24 @@ async function runRecorder({ name }) {
28
50
  process.exit(1);
29
51
  }
30
52
  try {
31
- // Prepare playwright for codegen
32
- console.log("[generateTestWithBrowserAgent] Preparing playwright for codegen");
53
+ logger_1.logger.debug("[generateTestWithBrowserAgent] Preparing playwright for codegen");
33
54
  await (0, pw_pause_1.preparePlaywrightForCodegen)(repoDir);
34
55
  }
35
56
  catch (err) {
36
- console.warn("[generateTestWithBrowserAgent] Error preparing playwright for codegen", err);
57
+ logger_1.logger.warn("[generateTestWithBrowserAgent] Error preparing playwright for codegen", err);
37
58
  }
38
59
  const envVariables = await (0, env_variables_1.fetchEnvironmentVariables)(repoName);
39
- await (0, temp_files_1.createTempTestFile)();
40
- const absFilePath = path_1.default.join(process.cwd(), "tests", "temp-test.spec.ts");
41
- await (0, utils_1.addImportForMethod)(absFilePath, "recordTest");
42
60
  // Start a file service for IPC with the agent (which runs in a different process)
43
61
  const availablePort = await (0, detect_port_1.default)(3030);
44
- const fileServer = new server_1.FileServiceServer({
62
+ fileServer = new server_1.FileServiceServer({
45
63
  port: availablePort,
46
64
  repoDir,
47
65
  updateFile: false,
48
66
  });
49
67
  await fileServer.startFileService();
68
+ await (0, temp_files_1.createTempTestFile)(availablePort);
69
+ const absFilePath = path_1.default.join(process.cwd(), "tests", "temp-test.spec.ts");
70
+ await (0, utils_1.addImportForMethod)(absFilePath, "recordTest");
50
71
  await (0, test_run_1.runSingleTest)({
51
72
  testName: "temp test",
52
73
  suites: [],
@@ -63,7 +84,7 @@ async function runRecorder({ name }) {
63
84
  const videoPaths = (0, upload_1.extractVideoAttachments)(repoDir);
64
85
  let attachments = [];
65
86
  if (videoPaths.length === 0) {
66
- console.warn("No video attachments found for temp test");
87
+ logger_1.logger.warn("No video attachments found for temp test");
67
88
  }
68
89
  else {
69
90
  const videoUrls = await (0, upload_1.uploadVideosWithSpinner)(videoPaths, name);
@@ -75,11 +96,10 @@ async function runRecorder({ name }) {
75
96
  await (0, pw_pause_1.revertToOriginalPwCode)(repoDir);
76
97
  const codegenResult = fileServer.getCodegenSources();
77
98
  await fileServer.stop();
78
- const finalCode = await (0, display_1.displayResultsAndConfirm)(name, codegenResult);
79
99
  await (0, request_1.sendToDashboardAsRequest)({
80
100
  repoName,
81
101
  testName: name,
82
- codegenResult: finalCode,
102
+ codegenResult: codegenResult,
83
103
  attachments,
84
104
  });
85
105
  }
@@ -1 +1 @@
1
- {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/recorder/request.ts"],"names":[],"mappings":"AAcA,wBAAsB,wBAAwB,CAAC,EAC7C,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,WAAW,GACZ,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,iBAMA"}
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/recorder/request.ts"],"names":[],"mappings":"AA+KA,wBAAsB,wBAAwB,CAAC,EAC7C,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,WAAW,GACZ,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,iBAmBA"}
@@ -1,22 +1,172 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.sendToDashboardAsRequest = sendToDashboardAsRequest;
7
+ const inquirer_1 = __importDefault(require("inquirer"));
4
8
  const api_client_1 = require("../auth/api-client");
5
- const title = (name) => `Add a test: ${name}`;
6
- function description(codegenResult, attachments) {
9
+ function truncateForDisplay(text, maxLineLength) {
10
+ const lines = text.split("\n");
11
+ return lines
12
+ .map((line) => {
13
+ if (line.length <= maxLineLength) {
14
+ return line;
15
+ }
16
+ return line.substring(0, maxLineLength - 3) + "...";
17
+ })
18
+ .join("\n");
19
+ }
20
+ function wrapText(text, width) {
21
+ const allLines = [];
22
+ // Split by newlines first to preserve existing line breaks
23
+ const paragraphs = text.split("\n");
24
+ for (const paragraph of paragraphs) {
25
+ if (paragraph.trim() === "") {
26
+ allLines.push("");
27
+ continue;
28
+ }
29
+ // If the line is already shorter than width, use it as-is
30
+ if (paragraph.length <= width) {
31
+ allLines.push(paragraph);
32
+ continue;
33
+ }
34
+ // Otherwise, wrap the line
35
+ const words = paragraph.split(" ");
36
+ let currentLine = "";
37
+ for (const word of words) {
38
+ if (currentLine.length + word.length + 1 <= width) {
39
+ currentLine += (currentLine.length > 0 ? " " : "") + word;
40
+ }
41
+ else {
42
+ if (currentLine.length > 0) {
43
+ allLines.push(currentLine);
44
+ currentLine = word;
45
+ }
46
+ else {
47
+ // Word is longer than width, split it into chunks
48
+ if (word.length > width) {
49
+ let remainingWord = word;
50
+ while (remainingWord.length > width) {
51
+ allLines.push(remainingWord.substring(0, width));
52
+ remainingWord = remainingWord.substring(width);
53
+ }
54
+ currentLine = remainingWord;
55
+ }
56
+ else {
57
+ currentLine = word;
58
+ }
59
+ }
60
+ }
61
+ }
62
+ if (currentLine.length > 0) {
63
+ allLines.push(currentLine);
64
+ }
65
+ }
66
+ return allLines;
67
+ }
68
+ function printInBox(header, title, description) {
69
+ const boxWidth = 80;
70
+ const contentWidth = boxWidth - 4; // Account for borders and padding
71
+ // Create box with padding
72
+ console.log("\n" + "┌" + "─".repeat(boxWidth - 2) + "┐");
73
+ // Header section
74
+ console.log("│ " + header + " ".repeat(boxWidth - 4 - header.length) + "│");
75
+ console.log("│" + "─".repeat(boxWidth - 2) + "│");
76
+ // Title content with wrapping
77
+ const titleLines = wrapText(title, contentWidth - 2);
78
+ titleLines.forEach((line) => {
79
+ const padding = Math.max(0, boxWidth - 4 - line.length);
80
+ console.log("│ " + line + " ".repeat(padding) + "│");
81
+ });
82
+ console.log("│" + "─".repeat(boxWidth - 2) + "│");
83
+ console.log("│ Description:" + " ".repeat(boxWidth - 16) + "│");
84
+ console.log("│" + " ".repeat(boxWidth - 2) + "│");
85
+ // Description content with wrapping
86
+ const descriptionLines = wrapText(description, contentWidth - 2);
87
+ descriptionLines.forEach((line) => {
88
+ const padding = Math.max(0, boxWidth - 4 - line.length);
89
+ console.log("│ " + line + " ".repeat(padding) + "│");
90
+ });
91
+ console.log("│" + " ".repeat(boxWidth - 2) + "│");
92
+ console.log("└" + "─".repeat(boxWidth - 2) + "┘");
93
+ }
94
+ const defaultTitle = (name) => `Add a test: ${name}`;
95
+ function defaultDescription(codegenResult, attachments) {
96
+ const backtickedCodegenResult = `\`\`\`\n${codegenResult}\n\`\`\``;
97
+ return [
98
+ `To add this test, refer to the following code and videos that were captured using playwright codegen. Make modifications that you need to make to convert this into a test case that sits well with other tests in this repository.`,
99
+ `Codegen result:`,
100
+ backtickedCodegenResult,
101
+ ...attachments.map((attachment) => `[[${attachment}]]`),
102
+ ].join("\n\n");
103
+ }
104
+ function defaultDescriptionForDisplay(codegenResult, attachments) {
105
+ const truncatedCodegenResult = truncateForDisplay(codegenResult, 74);
106
+ const backtickedCodegenResult = `\`\`\`\n${truncatedCodegenResult}\n\`\`\``;
7
107
  return [
8
- `To add this test, refer to the following code that was captured using playwright codegen. Make modifications that you need to make to convert this into a test case that sits well with other tests in this repository.`,
108
+ `To add this test, refer to the following code and videos that were captured using playwright codegen. Make modifications that you need to make to convert this into a test case that sits well with other tests in this repository.`,
9
109
  `Codegen result:`,
10
- codegenResult,
11
- `Other attachments:`,
12
- ...attachments,
110
+ backtickedCodegenResult,
111
+ ...attachments.map((attachment) => `[[${attachment}]]`),
13
112
  ].join("\n\n");
14
113
  }
114
+ async function confirmRequestDetails(initialTitle, initialDescription, initialDescriptionForDisplay) {
115
+ let finalTitle = initialTitle;
116
+ let finalDescription = initialDescription;
117
+ let finalDescriptionForDisplay = initialDescriptionForDisplay;
118
+ let approved = false;
119
+ while (!approved) {
120
+ printInBox("📝 Create new request", finalTitle, finalDescriptionForDisplay);
121
+ const { confirmed } = await inquirer_1.default.prompt([
122
+ {
123
+ type: "confirm",
124
+ name: "confirmed",
125
+ message: "Does this look good to send to the dashboard?",
126
+ default: true,
127
+ },
128
+ ]);
129
+ if (confirmed) {
130
+ console.log("✅ Great! Sending request to dashboard...");
131
+ approved = true;
132
+ }
133
+ else {
134
+ // Let user edit title and description
135
+ const { editedTitle } = await inquirer_1.default.prompt([
136
+ {
137
+ type: "input",
138
+ name: "editedTitle",
139
+ message: "Edit the title:",
140
+ default: finalTitle,
141
+ },
142
+ ]);
143
+ const { editedDescription } = await inquirer_1.default.prompt([
144
+ {
145
+ type: "editor",
146
+ name: "editedDescription",
147
+ message: "Edit the description:",
148
+ default: finalDescription,
149
+ },
150
+ ]);
151
+ finalTitle = editedTitle;
152
+ finalDescription = editedDescription;
153
+ // For simplicity, if description is edited, just use it as-is for display
154
+ finalDescriptionForDisplay = editedDescription;
155
+ console.clear();
156
+ console.log("Request details updated.");
157
+ }
158
+ }
159
+ return { title: finalTitle, description: finalDescription };
160
+ }
15
161
  async function sendToDashboardAsRequest({ repoName, testName, codegenResult, attachments, }) {
162
+ const initialTitle = defaultTitle(testName);
163
+ const initialDescription = defaultDescription(codegenResult, attachments);
164
+ const initialDescriptionForDisplay = defaultDescriptionForDisplay(codegenResult, attachments);
165
+ const { title, description } = await confirmRequestDetails(initialTitle, initialDescription, initialDescriptionForDisplay);
16
166
  return createRequest({
17
167
  repoName,
18
- title: title(testName),
19
- description: description(codegenResult, attachments),
168
+ title,
169
+ description,
20
170
  });
21
171
  }
22
172
  async function createRequest({ repoName, title, description, }) {
@@ -1,3 +1,3 @@
1
- export declare function createTempTestFile(): Promise<void>;
1
+ export declare function createTempTestFile(port: number): Promise<void>;
2
2
  export declare function deleteTempTestFile(): Promise<void>;
3
3
  //# sourceMappingURL=temp-files.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"temp-files.d.ts","sourceRoot":"","sources":["../../src/recorder/temp-files.ts"],"names":[],"mappings":"AAGA,wBAAsB,kBAAkB,kBAoBvC;AAED,wBAAsB,kBAAkB,kBAUvC"}
1
+ {"version":3,"file":"temp-files.d.ts","sourceRoot":"","sources":["../../src/recorder/temp-files.ts"],"names":[],"mappings":"AAKA,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,iBAmBpD;AAED,wBAAsB,kBAAkB,kBAUvC"}
@@ -7,33 +7,33 @@ exports.createTempTestFile = createTempTestFile;
7
7
  exports.deleteTempTestFile = deleteTempTestFile;
8
8
  const fs_1 = __importDefault(require("fs"));
9
9
  const path_1 = __importDefault(require("path"));
10
- async function createTempTestFile() {
10
+ const logger_1 = require("../logger");
11
+ async function createTempTestFile(port) {
11
12
  const tempFilePath = path_1.default.join(process.cwd(), "tests", "temp-test.spec.ts");
12
13
  // Check if the temp file already exists
13
14
  if (fs_1.default.existsSync(tempFilePath)) {
14
- console.warn("Temporary test file already exists. Skipping creation.");
15
+ logger_1.logger.warn("Temporary test file already exists. Skipping creation.");
15
16
  return;
16
17
  }
17
18
  // Create a basic test file
18
19
  const content = `import { test, expect } from './fixtures';
19
20
 
20
21
  test('temp test', async ({ page }) => {
21
- await page.goto('https://example.com');
22
- expect(await page.title()).toBe('Example Domain');
22
+ await page.goto('http://localhost:${port}/ready');
23
23
  await recordTest(page);
24
24
  });
25
25
  `;
26
26
  fs_1.default.writeFileSync(tempFilePath, content);
27
- console.log("Temporary test file created:", tempFilePath);
27
+ logger_1.logger.debug("Temporary test file created:", tempFilePath);
28
28
  }
29
29
  async function deleteTempTestFile() {
30
30
  const tempFilePath = path_1.default.join(process.cwd(), "tests", "temp-test.spec.ts");
31
31
  // Check if the temp file exists
32
32
  if (fs_1.default.existsSync(tempFilePath)) {
33
33
  fs_1.default.unlinkSync(tempFilePath);
34
- console.log("Temporary test file deleted:", tempFilePath);
34
+ logger_1.logger.debug("Temporary test file deleted:", tempFilePath);
35
35
  }
36
36
  else {
37
- console.warn("Temporary test file does not exist. Skipping deletion.");
37
+ logger_1.logger.warn("Temporary test file does not exist. Skipping deletion.");
38
38
  }
39
39
  }
@@ -1 +1 @@
1
- {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/recorder/upload.ts"],"names":[],"mappings":"AAcA,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAoBjE;AA4DD,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,MAAM,EAAE,EACpB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,GAAG,MAAM,EAAE,CAAC,CAe1B"}
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/recorder/upload.ts"],"names":[],"mappings":"AAcA,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAoBjE;AA4DD,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,MAAM,EAAE,EACpB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,GAAG,MAAM,EAAE,CAAC,CAc1B"}
@@ -79,7 +79,6 @@ async function uploadVideos(videoPaths, testSlug) {
79
79
  }
80
80
  }
81
81
  async function uploadVideosWithSpinner(videoPaths, testName) {
82
- videoPaths.forEach((videoPath) => console.log(videoPath));
83
82
  const uploadSpinner = (0, ora_1.default)("Uploading video recordings...").start();
84
83
  try {
85
84
  const slugifiedTestName = `${(0, slug_1.slugify)(testName)}-${Math.random().toString(36).substring(2, 8)}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empiricalrun/test-gen",
3
- "version": "0.68.0",
3
+ "version": "0.69.1",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"
@@ -42,6 +42,7 @@
42
42
  "@types/sanitize-html": "^2.11.0",
43
43
  "async-retry": "^1.3.3",
44
44
  "commander": "^12.1.0",
45
+ "console-log-level": "^1.4.1",
45
46
  "detect-port": "^1.6.1",
46
47
  "dotenv": "^16.4.5",
47
48
  "eslint": "^8.57.0",
@@ -63,13 +64,14 @@
63
64
  "tsx": "^4.16.2",
64
65
  "typescript": "^5.3.3",
65
66
  "zod": "^3.23.8",
66
- "@empiricalrun/llm": "^0.18.2",
67
+ "@empiricalrun/llm": "^0.19.0",
67
68
  "@empiricalrun/r2-uploader": "^0.3.9",
68
- "@empiricalrun/test-run": "^0.10.3"
69
+ "@empiricalrun/test-run": "^0.10.5"
69
70
  },
70
71
  "devDependencies": {
71
72
  "@playwright/test": "1.53.0",
72
73
  "@types/async-retry": "^1.4.8",
74
+ "@types/console-log-level": "^1.4.5",
73
75
  "@types/detect-port": "^1.3.5",
74
76
  "@types/express": "^4.17.21",
75
77
  "@types/js-levenshtein": "^1.1.3",
@@ -80,7 +82,7 @@
80
82
  "playwright": "1.53.0",
81
83
  "serve-handler": "^6.1.6",
82
84
  "ts-patch": "^3.3.0",
83
- "@empiricalrun/shared-types": "0.5.2"
85
+ "@empiricalrun/shared-types": "0.6.0"
84
86
  },
85
87
  "scripts": {
86
88
  "dev": "tspc --build --watch",
@@ -1 +1 @@
1
- {"root":["./src/index.ts","./src/actions/assert.ts","./src/actions/click.ts","./src/actions/done.ts","./src/actions/fill.ts","./src/actions/goto.ts","./src/actions/hover.ts","./src/actions/index.ts","./src/actions/next-task.ts","./src/actions/press.ts","./src/actions/skill.ts","./src/actions/text-content.ts","./src/actions/constants/index.ts","./src/actions/utils/index.ts","./src/agent/browsing/index.ts","./src/agent/browsing/run.ts","./src/agent/browsing/utils.ts","./src/agent/chat/agent-loop.ts","./src/agent/chat/exports.ts","./src/agent/chat/index.ts","./src/agent/chat/models.ts","./src/agent/chat/state.ts","./src/agent/chat/types.ts","./src/agent/chat/utils.ts","./src/agent/chat/prompt/index.ts","./src/agent/chat/prompt/pw-utils-docs.ts","./src/agent/chat/prompt/repo.ts","./src/agent/codegen/create-test-block.ts","./src/agent/codegen/fix-ts-errors.ts","./src/agent/codegen/generate-code-apply-changes.ts","./src/agent/codegen/lexical-scoped-vars.ts","./src/agent/codegen/repo-edit.ts","./src/agent/codegen/run.ts","./src/agent/codegen/skills-retriever.ts","./src/agent/codegen/test-update-feedback.ts","./src/agent/codegen/types.ts","./src/agent/codegen/update-flow.ts","./src/agent/codegen/use-skill.ts","./src/agent/codegen/utils.ts","./src/agent/cua/computer.ts","./src/agent/cua/index.ts","./src/agent/cua/model.ts","./src/agent/cua/pw-codegen/element-from-point.ts","./src/agent/cua/pw-codegen/types.ts","./src/agent/cua/pw-codegen/pw-pause/for-recorder.ts","./src/agent/cua/pw-codegen/pw-pause/index.ts","./src/agent/cua/pw-codegen/pw-pause/ipc.ts","./src/agent/cua/pw-codegen/pw-pause/patch.ts","./src/agent/cua/pw-codegen/pw-pause/types.ts","./src/agent/diagnosis-agent/index.ts","./src/agent/diagnosis-agent/strict-mode-violation.ts","./src/agent/enrich-prompt/index.ts","./src/agent/enrich-prompt/utils.ts","./src/agent/infer-agent/index.ts","./src/agent/master/action-tool-calls.ts","./src/agent/master/element-annotation.ts","./src/agent/master/execute-browser-action.ts","./src/agent/master/execute-skill-action.ts","./src/agent/master/next-action.ts","./src/agent/master/planner.ts","./src/agent/master/run.ts","./src/agent/master/scroller.ts","./src/agent/master/with-hints.ts","./src/agent/master/browser-tests/cua.spec.ts","./src/agent/master/browser-tests/fixtures.ts","./src/agent/master/browser-tests/index.spec.ts","./src/agent/master/browser-tests/skills.spec.ts","./src/agent/master/icon-descriptor/index.ts","./src/agent/master/icon-descriptor/normalize-svg.ts","./src/agent/planner/run-time-planner.ts","./src/agent/planner/run.ts","./src/artifacts/index.ts","./src/artifacts/utils.ts","./src/auth/api-client.ts","./src/auth/cli-auth.ts","./src/auth/index.ts","./src/auth/token-store.ts","./src/bin/index.ts","./src/bin/logger/index.ts","./src/bin/utils/context.ts","./src/bin/utils/index.ts","./src/bin/utils/fs/index.ts","./src/bin/utils/platform/web/index.ts","./src/bin/utils/platform/web/test-files/ts-path-import-validate.ts","./src/bin/utils/scenarios/index.ts","./src/browser-injected-scripts/annotate-elements.spec.ts","./src/constants/index.ts","./src/errors/index.ts","./src/evals/add-scenario-agent.evals.ts","./src/evals/append-create-test-agent.evals.ts","./src/evals/fetch-pom-skills-agent.evals.ts","./src/evals/infer-master-or-code-agent.evals.ts","./src/evals/master-agent.evals.ts","./src/evals/type.ts","./src/evals/update-scenario-agent.evals.ts","./src/file/client.ts","./src/file/server.ts","./src/human-in-the-loop/cli.ts","./src/human-in-the-loop/index.ts","./src/human-in-the-loop/ipc.ts","./src/page/index.ts","./src/prompts/lib/ts-transformer.ts","./src/recorder/display.ts","./src/recorder/env-variables.ts","./src/recorder/index.ts","./src/recorder/request.ts","./src/recorder/temp-files.ts","./src/recorder/upload.ts","./src/recorder/validation.ts","./src/reporter/index.ts","./src/reporter/lib.ts","./src/session/index.ts","./src/test-build/index.ts","./src/tool-call-service/index.ts","./src/tool-call-service/utils.ts","./src/tools/commit-and-create-pr.ts","./src/tools/diagnosis-fetcher.ts","./src/tools/download-build.ts","./src/tools/list-environments.ts","./src/tools/str_replace_editor.ts","./src/tools/test-gen-browser.ts","./src/tools/test-run.ts","./src/tools/grep/index.ts","./src/tools/grep/ripgrep/index.ts","./src/tools/grep/ripgrep/types.ts","./src/tools/test-run-fetcher/index.ts","./src/tools/test-run-fetcher/types.ts","./src/tools/upgrade-packages/index.ts","./src/tools/upgrade-packages/utils.ts","./src/tools/utils/index.ts","./src/types/handlebars.d.ts","./src/types/index.ts","./src/uploader/index.ts","./src/uploader/utils.ts","./src/utils/checkpoint.ts","./src/utils/env.ts","./src/utils/exec.ts","./src/utils/file-tree.ts","./src/utils/file.ts","./src/utils/git.ts","./src/utils/html.ts","./src/utils/index.ts","./src/utils/json.ts","./src/utils/repo-tree.ts","./src/utils/slug.ts","./src/utils/string.ts","./src/utils/stripAnsi.ts"],"version":"5.8.3"}
1
+ {"root":["./src/index.ts","./src/logger.ts","./src/actions/assert.ts","./src/actions/click.ts","./src/actions/done.ts","./src/actions/fill.ts","./src/actions/goto.ts","./src/actions/hover.ts","./src/actions/index.ts","./src/actions/next-task.ts","./src/actions/press.ts","./src/actions/skill.ts","./src/actions/text-content.ts","./src/actions/constants/index.ts","./src/actions/utils/index.ts","./src/agent/browsing/index.ts","./src/agent/browsing/run.ts","./src/agent/browsing/utils.ts","./src/agent/chat/agent-loop.ts","./src/agent/chat/exports.ts","./src/agent/chat/index.ts","./src/agent/chat/models.ts","./src/agent/chat/state.ts","./src/agent/chat/types.ts","./src/agent/chat/utils.ts","./src/agent/chat/prompt/index.ts","./src/agent/chat/prompt/pw-utils-docs.ts","./src/agent/chat/prompt/repo.ts","./src/agent/codegen/create-test-block.ts","./src/agent/codegen/fix-ts-errors.ts","./src/agent/codegen/generate-code-apply-changes.ts","./src/agent/codegen/lexical-scoped-vars.ts","./src/agent/codegen/repo-edit.ts","./src/agent/codegen/run.ts","./src/agent/codegen/skills-retriever.ts","./src/agent/codegen/test-update-feedback.ts","./src/agent/codegen/types.ts","./src/agent/codegen/update-flow.ts","./src/agent/codegen/use-skill.ts","./src/agent/codegen/utils.ts","./src/agent/cua/computer.ts","./src/agent/cua/index.ts","./src/agent/cua/model.ts","./src/agent/cua/pw-codegen/element-from-point.ts","./src/agent/cua/pw-codegen/types.ts","./src/agent/cua/pw-codegen/pw-pause/for-recorder.ts","./src/agent/cua/pw-codegen/pw-pause/index.ts","./src/agent/cua/pw-codegen/pw-pause/ipc.ts","./src/agent/cua/pw-codegen/pw-pause/patch.ts","./src/agent/cua/pw-codegen/pw-pause/types.ts","./src/agent/diagnosis-agent/index.ts","./src/agent/diagnosis-agent/strict-mode-violation.ts","./src/agent/enrich-prompt/index.ts","./src/agent/enrich-prompt/utils.ts","./src/agent/infer-agent/index.ts","./src/agent/master/action-tool-calls.ts","./src/agent/master/element-annotation.ts","./src/agent/master/execute-browser-action.ts","./src/agent/master/execute-skill-action.ts","./src/agent/master/next-action.ts","./src/agent/master/planner.ts","./src/agent/master/run.ts","./src/agent/master/scroller.ts","./src/agent/master/with-hints.ts","./src/agent/master/browser-tests/cua.spec.ts","./src/agent/master/browser-tests/fixtures.ts","./src/agent/master/browser-tests/index.spec.ts","./src/agent/master/browser-tests/skills.spec.ts","./src/agent/master/icon-descriptor/index.ts","./src/agent/master/icon-descriptor/normalize-svg.ts","./src/agent/planner/run-time-planner.ts","./src/agent/planner/run.ts","./src/artifacts/index.ts","./src/artifacts/utils.ts","./src/auth/api-client.ts","./src/auth/cli-auth.ts","./src/auth/index.ts","./src/auth/token-store.ts","./src/bin/index.ts","./src/bin/setup.ts","./src/bin/logger/index.ts","./src/bin/utils/context.ts","./src/bin/utils/index.ts","./src/bin/utils/fs/index.ts","./src/bin/utils/platform/web/index.ts","./src/bin/utils/platform/web/test-files/ts-path-import-validate.ts","./src/bin/utils/scenarios/index.ts","./src/browser-injected-scripts/annotate-elements.spec.ts","./src/constants/index.ts","./src/errors/index.ts","./src/evals/add-scenario-agent.evals.ts","./src/evals/append-create-test-agent.evals.ts","./src/evals/fetch-pom-skills-agent.evals.ts","./src/evals/infer-master-or-code-agent.evals.ts","./src/evals/master-agent.evals.ts","./src/evals/type.ts","./src/evals/update-scenario-agent.evals.ts","./src/file/client.ts","./src/file/server.ts","./src/human-in-the-loop/cli.ts","./src/human-in-the-loop/index.ts","./src/human-in-the-loop/ipc.ts","./src/page/index.ts","./src/prompts/lib/ts-transformer.ts","./src/recorder/env-variables.ts","./src/recorder/index.ts","./src/recorder/request.ts","./src/recorder/temp-files.ts","./src/recorder/upload.ts","./src/recorder/validation.ts","./src/reporter/index.ts","./src/reporter/lib.ts","./src/session/index.ts","./src/test-build/index.ts","./src/tool-call-service/index.ts","./src/tool-call-service/utils.ts","./src/tools/commit-and-create-pr.ts","./src/tools/diagnosis-fetcher.ts","./src/tools/download-build.ts","./src/tools/list-environments.ts","./src/tools/str_replace_editor.ts","./src/tools/test-gen-browser.ts","./src/tools/test-run.ts","./src/tools/grep/index.ts","./src/tools/grep/ripgrep/index.ts","./src/tools/grep/ripgrep/types.ts","./src/tools/test-run-fetcher/index.ts","./src/tools/test-run-fetcher/types.ts","./src/tools/upgrade-packages/index.ts","./src/tools/upgrade-packages/utils.ts","./src/tools/utils/index.ts","./src/types/handlebars.d.ts","./src/types/index.ts","./src/uploader/index.ts","./src/uploader/utils.ts","./src/utils/checkpoint.ts","./src/utils/env.ts","./src/utils/exec.ts","./src/utils/file-tree.ts","./src/utils/file.ts","./src/utils/git.ts","./src/utils/html.ts","./src/utils/index.ts","./src/utils/json.ts","./src/utils/repo-tree.ts","./src/utils/slug.ts","./src/utils/string.ts","./src/utils/stripAnsi.ts"],"version":"5.8.3"}
@@ -1,2 +0,0 @@
1
- export declare function displayResultsAndConfirm(name: string, codegenResult: string): Promise<string>;
2
- //# sourceMappingURL=display.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../../src/recorder/display.ts"],"names":[],"mappings":"AAEA,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,MAAM,mBA+CtB"}
@@ -1,50 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.displayResultsAndConfirm = displayResultsAndConfirm;
7
- const inquirer_1 = __importDefault(require("inquirer"));
8
- async function displayResultsAndConfirm(name, codegenResult) {
9
- let finalResult = codegenResult || "No code generated";
10
- let approved = false;
11
- while (!approved) {
12
- // Display results in a box format
13
- console.log("\n" + "=".repeat(80));
14
- console.log("📝 TEST GENERATION RESULTS");
15
- console.log("=".repeat(80));
16
- console.log(`Test Name: ${name}`);
17
- console.log("-".repeat(80));
18
- console.log("Generated Code:");
19
- console.log("-".repeat(80));
20
- console.log(finalResult);
21
- console.log("=".repeat(80));
22
- // Ask user for confirmation
23
- const { confirmed } = await inquirer_1.default.prompt([
24
- {
25
- type: "confirm",
26
- name: "confirmed",
27
- message: "Does this look good to you?",
28
- default: true,
29
- },
30
- ]);
31
- if (confirmed) {
32
- console.log("✅ Great! The test generation was successful.");
33
- approved = true;
34
- }
35
- else {
36
- // Open multiline editor for user to modify
37
- const { editedCode } = await inquirer_1.default.prompt([
38
- {
39
- type: "editor",
40
- name: "editedCode",
41
- message: "Edit the generated code:",
42
- default: finalResult,
43
- },
44
- ]);
45
- finalResult = editedCode;
46
- console.log("Code updated. Let's review the changes...");
47
- }
48
- }
49
- return finalResult;
50
- }