@empiricalrun/test-gen 0.67.0 → 0.68.0
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 +6 -0
- package/dist/auth/api-client.d.ts +1 -2
- package/dist/auth/api-client.d.ts.map +1 -1
- package/dist/auth/api-client.js +13 -44
- package/dist/auth/index.d.ts +1 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +1 -4
- package/dist/bin/index.js +95 -109
- package/dist/bin/utils/index.d.ts +1 -7
- package/dist/bin/utils/index.d.ts.map +1 -1
- package/dist/bin/utils/index.js +1 -9
- package/dist/recorder/env-variables.d.ts +2 -0
- package/dist/recorder/env-variables.d.ts.map +1 -0
- package/dist/recorder/env-variables.js +29 -0
- package/dist/recorder/index.d.ts.map +1 -1
- package/dist/recorder/index.js +6 -29
- package/dist/recorder/request.d.ts +2 -1
- package/dist/recorder/request.d.ts.map +1 -1
- package/dist/recorder/request.js +13 -18
- package/dist/recorder/upload.d.ts +1 -0
- package/dist/recorder/upload.d.ts.map +1 -1
- package/dist/recorder/upload.js +23 -10
- package/dist/recorder/validation.d.ts +1 -1
- package/dist/recorder/validation.d.ts.map +1 -1
- package/dist/recorder/validation.js +9 -4
- package/package.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,5 @@ declare class APIClient {
|
|
|
7
7
|
private refreshToken;
|
|
8
8
|
}
|
|
9
9
|
export declare const apiClient: APIClient;
|
|
10
|
-
export {
|
|
11
|
-
export declare function authenticatedFetch(endpoint: string, options?: RequestInit): Promise<any>;
|
|
10
|
+
export {};
|
|
12
11
|
//# sourceMappingURL=api-client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/auth/api-client.ts"],"names":[],"mappings":"AAOA,cAAM,SAAS;IACb,OAAO,CAAC,MAAM,CAAS;;IAMjB,OAAO,CACX,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/auth/api-client.ts"],"names":[],"mappings":"AAOA,cAAM,SAAS;IACb,OAAO,CAAC,MAAM,CAAS;;IAMjB,OAAO,CACX,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,QAAQ,CAAC;YA2BN,WAAW;YAuBX,mBAAmB;YAiBnB,YAAY;CA4C3B;AAED,eAAO,MAAM,SAAS,WAAkB,CAAC"}
|
package/dist/auth/api-client.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.authenticatedFetch = authenticatedFetch;
|
|
3
|
+
exports.apiClient = void 0;
|
|
5
4
|
const token_store_1 = require("./token-store");
|
|
6
5
|
class APIClient {
|
|
7
6
|
appUrl;
|
|
@@ -9,17 +8,14 @@ class APIClient {
|
|
|
9
8
|
this.appUrl = process.env.DASHBOARD_DOMAIN || "https://dash.empirical.run";
|
|
10
9
|
}
|
|
11
10
|
async request(endpoint, options = {}) {
|
|
12
|
-
// Ensure user is authenticated
|
|
13
11
|
await this.ensureAuthenticated();
|
|
14
12
|
const tokens = await (0, token_store_1.getStoredTokens)();
|
|
15
13
|
if (!tokens) {
|
|
16
14
|
throw new Error("Not authenticated. Please run the login command first.");
|
|
17
15
|
}
|
|
18
|
-
// Make the request with the access token
|
|
19
16
|
const response = await this.makeRequest(endpoint, options, tokens.access_token);
|
|
20
|
-
// If token is expired, try refreshing and retry once
|
|
21
17
|
if (response.status === 401) {
|
|
22
|
-
console.log("Access token expired, attempting to refresh...");
|
|
18
|
+
// console.log("Access token expired, attempting to refresh...");
|
|
23
19
|
const refreshed = await this.refreshToken();
|
|
24
20
|
if (refreshed) {
|
|
25
21
|
const newTokens = await (0, token_store_1.getStoredTokens)();
|
|
@@ -34,14 +30,19 @@ class APIClient {
|
|
|
34
30
|
async makeRequest(endpoint, options, accessToken) {
|
|
35
31
|
const url = endpoint.startsWith("http")
|
|
36
32
|
? endpoint
|
|
37
|
-
: `${this.appUrl}
|
|
33
|
+
: `${this.appUrl}${endpoint}`;
|
|
34
|
+
// Don't set Content-Type for FormData (let browser set it automatically)
|
|
35
|
+
const headers = {
|
|
36
|
+
Authorization: `Bearer ${accessToken}`,
|
|
37
|
+
...options.headers,
|
|
38
|
+
};
|
|
39
|
+
// Only set Content-Type to application/json if body is not FormData
|
|
40
|
+
if (!(options.body instanceof FormData)) {
|
|
41
|
+
headers["Content-Type"] = "application/json";
|
|
42
|
+
}
|
|
38
43
|
return fetch(url, {
|
|
39
44
|
...options,
|
|
40
|
-
headers
|
|
41
|
-
Authorization: `Bearer ${accessToken}`,
|
|
42
|
-
"Content-Type": "application/json",
|
|
43
|
-
...options.headers,
|
|
44
|
-
},
|
|
45
|
+
headers,
|
|
45
46
|
});
|
|
46
47
|
}
|
|
47
48
|
async ensureAuthenticated() {
|
|
@@ -98,36 +99,4 @@ class APIClient {
|
|
|
98
99
|
}
|
|
99
100
|
}
|
|
100
101
|
}
|
|
101
|
-
exports.APIClient = APIClient;
|
|
102
102
|
exports.apiClient = new APIClient();
|
|
103
|
-
async function authenticatedFetch(endpoint, options) {
|
|
104
|
-
try {
|
|
105
|
-
const response = await exports.apiClient.request(endpoint, options);
|
|
106
|
-
if (!response.ok) {
|
|
107
|
-
const errorText = await response.text();
|
|
108
|
-
let errorMessage;
|
|
109
|
-
try {
|
|
110
|
-
const errorJson = JSON.parse(errorText);
|
|
111
|
-
errorMessage =
|
|
112
|
-
errorJson.error || errorJson.message || "API request failed";
|
|
113
|
-
}
|
|
114
|
-
catch {
|
|
115
|
-
errorMessage =
|
|
116
|
-
errorText || `Request failed with status ${response.status}`;
|
|
117
|
-
}
|
|
118
|
-
throw new Error(errorMessage);
|
|
119
|
-
}
|
|
120
|
-
const contentType = response.headers.get("content-type");
|
|
121
|
-
if (contentType && contentType.includes("application/json")) {
|
|
122
|
-
return response.json();
|
|
123
|
-
}
|
|
124
|
-
return response.text();
|
|
125
|
-
}
|
|
126
|
-
catch (error) {
|
|
127
|
-
if (error.message.includes("Not authenticated") ||
|
|
128
|
-
error.message.includes("Please run the login command")) {
|
|
129
|
-
throw new Error("Authentication required. Please run: npx @empiricalrun/test-gen login");
|
|
130
|
-
}
|
|
131
|
-
throw error;
|
|
132
|
-
}
|
|
133
|
-
}
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { apiClient } from "./api-client";
|
|
2
2
|
export { authenticate, getAuthStatus, logout } from "./cli-auth";
|
|
3
3
|
export { clearTokens, getStoredTokens, isAuthenticated, type StoredTokens, storeTokens, } from "./token-store";
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/auth/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EACL,WAAW,EACX,eAAe,EACf,eAAe,EACf,KAAK,YAAY,EACjB,WAAW,GACZ,MAAM,eAAe,CAAC"}
|
package/dist/auth/index.js
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.storeTokens = exports.isAuthenticated = exports.getStoredTokens = exports.clearTokens = exports.logout = exports.getAuthStatus = exports.authenticate = exports.
|
|
4
|
-
// Export all auth-related functionality
|
|
3
|
+
exports.storeTokens = exports.isAuthenticated = exports.getStoredTokens = exports.clearTokens = exports.logout = exports.getAuthStatus = exports.authenticate = exports.apiClient = void 0;
|
|
5
4
|
var api_client_1 = require("./api-client");
|
|
6
|
-
Object.defineProperty(exports, "APIClient", { enumerable: true, get: function () { return api_client_1.APIClient; } });
|
|
7
5
|
Object.defineProperty(exports, "apiClient", { enumerable: true, get: function () { return api_client_1.apiClient; } });
|
|
8
|
-
Object.defineProperty(exports, "authenticatedFetch", { enumerable: true, get: function () { return api_client_1.authenticatedFetch; } });
|
|
9
6
|
var cli_auth_1 = require("./cli-auth");
|
|
10
7
|
Object.defineProperty(exports, "authenticate", { enumerable: true, get: function () { return cli_auth_1.authenticate; } });
|
|
11
8
|
Object.defineProperty(exports, "getAuthStatus", { enumerable: true, get: function () { return cli_auth_1.getAuthStatus; } });
|
package/dist/bin/index.js
CHANGED
|
@@ -17,6 +17,7 @@ const enrich_prompt_1 = require("../agent/enrich-prompt");
|
|
|
17
17
|
const infer_agent_1 = require("../agent/infer-agent");
|
|
18
18
|
const run_3 = require("../agent/planner/run");
|
|
19
19
|
const auth_1 = require("../auth");
|
|
20
|
+
const api_client_1 = require("../auth/api-client");
|
|
20
21
|
const recorder_1 = require("../recorder");
|
|
21
22
|
const reporter_1 = require("../reporter");
|
|
22
23
|
const session_1 = require("../session");
|
|
@@ -27,16 +28,6 @@ const scenarios_1 = require("./utils/scenarios");
|
|
|
27
28
|
dotenv_1.default.config({
|
|
28
29
|
path: [".env.local", ".env"],
|
|
29
30
|
});
|
|
30
|
-
const flushEvents = async () => {
|
|
31
|
-
await (0, llm_1.flushAllTraces)();
|
|
32
|
-
};
|
|
33
|
-
function setupProcessListeners(cleanup) {
|
|
34
|
-
const events = ["beforeExit", "exit", "SIGINT", "SIGTERM"];
|
|
35
|
-
events.forEach((event) => process.once(event, cleanup));
|
|
36
|
-
return () => {
|
|
37
|
-
events.forEach((event) => process.removeListener(event, cleanup));
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
31
|
async function runChatAgent({ modelInput, chatSessionId, useDiskForChatState, initialPromptPath, }) {
|
|
41
32
|
if (modelInput && !utils_2.ARGS_TO_MODEL_MAP[modelInput]) {
|
|
42
33
|
throw new Error(`Invalid chat model: ${modelInput}`);
|
|
@@ -201,13 +192,11 @@ async function runAgentsWorkflow(testGenConfig, testGenToken) {
|
|
|
201
192
|
return agent;
|
|
202
193
|
}
|
|
203
194
|
async function main() {
|
|
204
|
-
const removeListeners = setupProcessListeners(flushEvents);
|
|
205
195
|
await (0, utils_2.printBanner)();
|
|
206
196
|
const program = new commander_1.Command();
|
|
207
|
-
// Add authentication commands
|
|
208
197
|
program
|
|
209
198
|
.command("login")
|
|
210
|
-
.description("Authenticate with your Empirical
|
|
199
|
+
.description("Authenticate with your Empirical account")
|
|
211
200
|
.action(async () => {
|
|
212
201
|
console.log("🔐 Starting authentication...\n");
|
|
213
202
|
try {
|
|
@@ -232,7 +221,7 @@ async function main() {
|
|
|
232
221
|
});
|
|
233
222
|
program
|
|
234
223
|
.command("logout")
|
|
235
|
-
.description("Sign out of your Empirical
|
|
224
|
+
.description("Sign out of your Empirical account")
|
|
236
225
|
.action(async () => {
|
|
237
226
|
try {
|
|
238
227
|
await (0, auth_1.logout)();
|
|
@@ -265,118 +254,115 @@ async function main() {
|
|
|
265
254
|
console.error("❌ Error checking auth status:", error.message);
|
|
266
255
|
process.exit(1);
|
|
267
256
|
}
|
|
268
|
-
removeListeners();
|
|
269
|
-
await (0, llm_1.flushAllTraces)();
|
|
270
|
-
await (0, logger_1.waitForLogsToFlush)();
|
|
271
257
|
process.exit(0);
|
|
272
258
|
});
|
|
273
259
|
program
|
|
274
|
-
.command("
|
|
275
|
-
.description("
|
|
260
|
+
.command("record")
|
|
261
|
+
.description("Record a new test case")
|
|
262
|
+
.option("--name <string>", "Name of the test case")
|
|
263
|
+
.action(async (opts) => {
|
|
264
|
+
const options = await (0, utils_2.validateAndCompleteCliOptions)(opts, ["name"]);
|
|
265
|
+
await (0, recorder_1.runRecorder)({ name: options.name });
|
|
266
|
+
process.exit(0);
|
|
267
|
+
});
|
|
268
|
+
program
|
|
269
|
+
.command("repos")
|
|
270
|
+
.description("List your projects and repositories")
|
|
276
271
|
.action(async () => {
|
|
277
272
|
try {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
273
|
+
const response = await api_client_1.apiClient.request("/api/projects");
|
|
274
|
+
if (!response.ok) {
|
|
275
|
+
console.error("❌ Failed to fetch projects:", response.statusText);
|
|
276
|
+
process.exit(1);
|
|
277
|
+
}
|
|
278
|
+
const result = await response.json();
|
|
279
|
+
result.data.projects.forEach((project) => {
|
|
280
|
+
console.log(` ${project.repo_name}`);
|
|
281
|
+
});
|
|
282
282
|
}
|
|
283
283
|
catch (error) {
|
|
284
|
-
console.error("❌
|
|
285
|
-
if (error.message.includes("Authentication required")) {
|
|
286
|
-
console.log('\n💡 Tip: Run "npx @empiricalrun/test-gen login" to authenticate');
|
|
287
|
-
}
|
|
284
|
+
console.error("❌ Error fetching projects:", error.message);
|
|
288
285
|
process.exit(1);
|
|
289
286
|
}
|
|
290
|
-
removeListeners();
|
|
291
|
-
await (0, llm_1.flushAllTraces)();
|
|
292
|
-
await (0, logger_1.waitForLogsToFlush)();
|
|
293
287
|
process.exit(0);
|
|
294
288
|
});
|
|
295
289
|
program
|
|
296
|
-
.
|
|
297
|
-
.
|
|
298
|
-
.option("--
|
|
299
|
-
.option("--file <test-file>", "File path of the test case (inside tests dir)")
|
|
300
|
-
.option("--suites <suites>", "Comma separated list of describe blocks")
|
|
301
|
-
.option("--use-chat", "Use chat agent (and not the workflow)")
|
|
302
|
-
.option("--use-recorder", "Run the recorder flow to create a request")
|
|
303
|
-
.option("--chat-session-id <chat-session-id>", "Identifier for chat session (fetched from dash.empirical.run)")
|
|
290
|
+
.command("chat-agent")
|
|
291
|
+
.description("Run the chat agent")
|
|
292
|
+
.option("--chat-model <model>", "LLM to use (claude-3-7, claude-4 or gemini-2.5)")
|
|
304
293
|
.option("--use-disk-for-chat-state", "Save and load chat state from disk")
|
|
305
|
-
.option("--chat-model <model>", "Chat model to use (claude-3-7-sonnet-20250219 or claude-3-5-sonnet-20241022 or gemini-2.5-pro-preview-06-05)")
|
|
306
294
|
.option("--initial-prompt <path>", "Path to an initial prompt file (e.g. prompt.md)")
|
|
307
|
-
.option("--
|
|
308
|
-
.
|
|
309
|
-
// Check if a command was executed (auth commands exit early)
|
|
310
|
-
const options = program.opts();
|
|
311
|
-
// Only proceed with main workflow if no auth command was executed
|
|
312
|
-
const completedOptions = await (0, utils_2.validateAndCompleteCliOptions)(options);
|
|
313
|
-
const testGenConfig = completedOptions.token
|
|
314
|
-
? (0, scenarios_1.loadTestConfigs)(completedOptions.token)
|
|
315
|
-
: (0, scenarios_1.buildTestConfigFromOptions)(completedOptions);
|
|
316
|
-
const testGenToken = completedOptions.token
|
|
317
|
-
? completedOptions.token
|
|
318
|
-
: (0, scenarios_1.buildTokenFromOptions)(completedOptions);
|
|
319
|
-
(0, reporter_1.setReporterConfig)({
|
|
320
|
-
projectRepoName: testGenConfig.options?.metadata.projectRepoName,
|
|
321
|
-
testSessionId: testGenConfig.options?.metadata.testSessionId,
|
|
322
|
-
generationId: testGenConfig.options?.metadata.generationId,
|
|
323
|
-
});
|
|
324
|
-
(0, session_1.setSessionDetails)({
|
|
325
|
-
testCaseId: testGenConfig.testCase.id,
|
|
326
|
-
sessionId: testGenConfig.options?.metadata.testSessionId,
|
|
327
|
-
generationId: testGenConfig.options?.metadata.generationId,
|
|
328
|
-
projectRepoName: testGenConfig.options?.metadata.projectRepoName,
|
|
329
|
-
});
|
|
330
|
-
if (testGenConfig.build?.url) {
|
|
331
|
-
// Download the build if repo has a download script
|
|
332
|
-
await (0, test_build_1.downloadBuild)({
|
|
333
|
-
buildUrl: testGenConfig.build.url,
|
|
334
|
-
repoPath: process.cwd(),
|
|
335
|
-
apiKey: process.env.EMPIRICALRUN_API_KEY,
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
if (completedOptions.useRecorder) {
|
|
339
|
-
await (0, recorder_1.runRecorder)({ name: completedOptions.name });
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
342
|
-
if (completedOptions.useChat) {
|
|
295
|
+
.option("--chat-session-id <chat-session-id>", "Identifier for chat session (fetched from dash.empirical.run)")
|
|
296
|
+
.action(async (options) => {
|
|
343
297
|
await runChatAgent({
|
|
344
|
-
chatSessionId:
|
|
345
|
-
modelInput:
|
|
346
|
-
useDiskForChatState:
|
|
347
|
-
initialPromptPath:
|
|
348
|
-
});
|
|
349
|
-
return;
|
|
350
|
-
}
|
|
351
|
-
let agentUsed;
|
|
352
|
-
let testGenFailed = false;
|
|
353
|
-
try {
|
|
354
|
-
agentUsed = await runAgentsWorkflow(testGenConfig, testGenToken);
|
|
355
|
-
}
|
|
356
|
-
catch (e) {
|
|
357
|
-
testGenFailed = true;
|
|
358
|
-
new logger_1.CustomLogger().error(`Failed to generate test for the scenario. ${process.env.LOG_URL ? `[view log](${process.env.LOG_URL})` : ""}`, e?.message, e?.stack);
|
|
359
|
-
}
|
|
360
|
-
if (agentUsed &&
|
|
361
|
-
agentUsed !== "code" &&
|
|
362
|
-
agentUsed !== "plan" &&
|
|
363
|
-
testGenConfig.testCase.name &&
|
|
364
|
-
testGenConfig.options) {
|
|
365
|
-
await new reporter_1.TestGenUpdatesReporter().reportGenAssets({
|
|
366
|
-
projectRepoName: testGenConfig.options.metadata.projectRepoName,
|
|
367
|
-
testName: testGenConfig.testCase.name,
|
|
298
|
+
chatSessionId: options.chatSessionId,
|
|
299
|
+
modelInput: options.chatModel,
|
|
300
|
+
useDiskForChatState: options.useDiskForChatState,
|
|
301
|
+
initialPromptPath: options.initialPrompt,
|
|
368
302
|
});
|
|
369
|
-
}
|
|
370
|
-
removeListeners();
|
|
371
|
-
await (0, llm_1.flushAllTraces)();
|
|
372
|
-
await (0, logger_1.waitForLogsToFlush)();
|
|
373
|
-
await (0, session_1.endSession)();
|
|
374
|
-
if (testGenFailed) {
|
|
375
|
-
process.exit(1);
|
|
376
|
-
}
|
|
377
|
-
else {
|
|
378
303
|
process.exit(0);
|
|
379
|
-
}
|
|
304
|
+
});
|
|
305
|
+
program
|
|
306
|
+
.command("legacy")
|
|
307
|
+
.description("Run the legacy workflows")
|
|
308
|
+
.option("-t, --token <token>", "Test generation token")
|
|
309
|
+
.action(async (opts) => {
|
|
310
|
+
const options = await (0, utils_2.validateAndCompleteCliOptions)(opts);
|
|
311
|
+
const testGenConfig = options.token
|
|
312
|
+
? (0, scenarios_1.loadTestConfigs)(options.token)
|
|
313
|
+
: (0, scenarios_1.buildTestConfigFromOptions)(options);
|
|
314
|
+
const testGenToken = options.token
|
|
315
|
+
? options.token
|
|
316
|
+
: (0, scenarios_1.buildTokenFromOptions)(options);
|
|
317
|
+
(0, reporter_1.setReporterConfig)({
|
|
318
|
+
projectRepoName: testGenConfig.options?.metadata.projectRepoName,
|
|
319
|
+
testSessionId: testGenConfig.options?.metadata.testSessionId,
|
|
320
|
+
generationId: testGenConfig.options?.metadata.generationId,
|
|
321
|
+
});
|
|
322
|
+
(0, session_1.setSessionDetails)({
|
|
323
|
+
testCaseId: testGenConfig.testCase.id,
|
|
324
|
+
sessionId: testGenConfig.options?.metadata.testSessionId,
|
|
325
|
+
generationId: testGenConfig.options?.metadata.generationId,
|
|
326
|
+
projectRepoName: testGenConfig.options?.metadata.projectRepoName,
|
|
327
|
+
});
|
|
328
|
+
if (testGenConfig.build?.url) {
|
|
329
|
+
// Download the build if repo has a download script
|
|
330
|
+
await (0, test_build_1.downloadBuild)({
|
|
331
|
+
buildUrl: testGenConfig.build.url,
|
|
332
|
+
repoPath: process.cwd(),
|
|
333
|
+
apiKey: process.env.EMPIRICALRUN_API_KEY,
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
let agentUsed;
|
|
337
|
+
let testGenFailed = false;
|
|
338
|
+
try {
|
|
339
|
+
agentUsed = await runAgentsWorkflow(testGenConfig, testGenToken);
|
|
340
|
+
}
|
|
341
|
+
catch (e) {
|
|
342
|
+
testGenFailed = true;
|
|
343
|
+
new logger_1.CustomLogger().error(`Failed to generate test for the scenario. ${process.env.LOG_URL ? `[view log](${process.env.LOG_URL})` : ""}`, e?.message, e?.stack);
|
|
344
|
+
}
|
|
345
|
+
if (agentUsed &&
|
|
346
|
+
agentUsed !== "code" &&
|
|
347
|
+
agentUsed !== "plan" &&
|
|
348
|
+
testGenConfig.testCase.name &&
|
|
349
|
+
testGenConfig.options) {
|
|
350
|
+
await new reporter_1.TestGenUpdatesReporter().reportGenAssets({
|
|
351
|
+
projectRepoName: testGenConfig.options.metadata.projectRepoName,
|
|
352
|
+
testName: testGenConfig.testCase.name,
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
await (0, llm_1.flushAllTraces)();
|
|
356
|
+
await (0, logger_1.waitForLogsToFlush)();
|
|
357
|
+
await (0, session_1.endSession)();
|
|
358
|
+
if (testGenFailed) {
|
|
359
|
+
process.exit(1);
|
|
360
|
+
}
|
|
361
|
+
else {
|
|
362
|
+
process.exit(0);
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
program.parse(process.argv);
|
|
380
366
|
}
|
|
381
367
|
main().catch((error) => {
|
|
382
368
|
console.error("Unhandled error in main function:", error);
|
|
@@ -6,13 +6,7 @@ export interface CLIOptions {
|
|
|
6
6
|
file?: string;
|
|
7
7
|
prompt?: string;
|
|
8
8
|
suites?: string;
|
|
9
|
-
useChat?: boolean;
|
|
10
|
-
useDiskForChatState?: boolean;
|
|
11
|
-
initialPrompt?: string;
|
|
12
|
-
chatSessionId?: string;
|
|
13
|
-
chatModel?: (typeof ARGS_TO_MODEL_MAP)[keyof typeof ARGS_TO_MODEL_MAP];
|
|
14
|
-
useRecorder?: boolean;
|
|
15
9
|
}
|
|
16
|
-
export declare function validateAndCompleteCliOptions(options: CLIOptions): Promise<CLIOptions>;
|
|
10
|
+
export declare function validateAndCompleteCliOptions(options: CLIOptions, requiredFields?: string[]): Promise<CLIOptions>;
|
|
17
11
|
export declare function printBanner(): Promise<void>;
|
|
18
12
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bin/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAKjE,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAgBjE,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bin/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAKjE,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAgBjE,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAQD,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,UAAU,EACnB,cAAc,GAAE,MAAM,EAA+B,GACpD,OAAO,CAAC,UAAU,CAAC,CAqDrB;AAeD,wBAAsB,WAAW,kBAgDhC"}
|
package/dist/bin/utils/index.js
CHANGED
|
@@ -22,20 +22,12 @@ exports.ARGS_TO_MODEL_MAP = {
|
|
|
22
22
|
"o4-mini": "o4-mini-2025-04-16",
|
|
23
23
|
"o4-mini-2025-04-16": "o4-mini-2025-04-16",
|
|
24
24
|
};
|
|
25
|
-
async function validateAndCompleteCliOptions(options) {
|
|
25
|
+
async function validateAndCompleteCliOptions(options, requiredFields = ["name", "file", "prompt"]) {
|
|
26
26
|
// For existing flow between dashboard <> test-gen (via ci-worker)
|
|
27
27
|
const hasToken = !!options.token;
|
|
28
28
|
if (hasToken) {
|
|
29
29
|
return options;
|
|
30
30
|
}
|
|
31
|
-
let requiredFields = ["name", "file", "prompt"];
|
|
32
|
-
if (options.useChat) {
|
|
33
|
-
// Chat agent can prompt the user directly, nothing is required in CLI args
|
|
34
|
-
requiredFields = [];
|
|
35
|
-
}
|
|
36
|
-
if (options.useRecorder) {
|
|
37
|
-
requiredFields = ["name"];
|
|
38
|
-
}
|
|
39
31
|
const questions = [];
|
|
40
32
|
if (!options.name && requiredFields.includes("name")) {
|
|
41
33
|
questions.push({
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-variables.d.ts","sourceRoot":"","sources":["../../src/recorder/env-variables.ts"],"names":[],"mappings":"AAEA,wBAAsB,yBAAyB,CAC7C,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAgCjC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchEnvironmentVariables = fetchEnvironmentVariables;
|
|
4
|
+
const api_client_1 = require("../auth/api-client");
|
|
5
|
+
async function fetchEnvironmentVariables(repoName) {
|
|
6
|
+
try {
|
|
7
|
+
const response = await api_client_1.apiClient.request(`/api/environment-variables?project_repo_name=${encodeURIComponent(repoName)}`, {
|
|
8
|
+
method: "GET",
|
|
9
|
+
});
|
|
10
|
+
if (!response.ok) {
|
|
11
|
+
const errorMessage = await response.text();
|
|
12
|
+
throw new Error(`Failed to fetch environment variables: ${errorMessage}`);
|
|
13
|
+
}
|
|
14
|
+
const data = await response.json();
|
|
15
|
+
if (!data.data) {
|
|
16
|
+
console.error("Failed to fetch environment variables:", data);
|
|
17
|
+
throw new Error("Failed to fetch environment variables");
|
|
18
|
+
}
|
|
19
|
+
const envVars = data.data.environment_variables.reduce((acc, envVar) => {
|
|
20
|
+
acc[envVar.name] = envVar.value;
|
|
21
|
+
return acc;
|
|
22
|
+
}, {});
|
|
23
|
+
return envVars;
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
console.error("Failed to fetch environment variables:", error);
|
|
27
|
+
return {};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/recorder/index.ts"],"names":[],"mappings":"
|
|
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"}
|
package/dist/recorder/index.js
CHANGED
|
@@ -6,51 +6,27 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.runRecorder = runRecorder;
|
|
7
7
|
const test_run_1 = require("@empiricalrun/test-run");
|
|
8
8
|
const detect_port_1 = __importDefault(require("detect-port"));
|
|
9
|
-
const fs_1 = __importDefault(require("fs"));
|
|
10
9
|
const path_1 = __importDefault(require("path"));
|
|
11
10
|
const utils_1 = require("../agent/browsing/utils");
|
|
12
|
-
const chat_1 = require("../agent/chat");
|
|
13
11
|
const pw_pause_1 = require("../agent/cua/pw-codegen/pw-pause");
|
|
14
|
-
const utils_2 = require("../artifacts/utils");
|
|
15
12
|
const server_1 = require("../file/server");
|
|
16
13
|
const display_1 = require("./display");
|
|
14
|
+
const env_variables_1 = require("./env-variables");
|
|
17
15
|
const request_1 = require("./request");
|
|
18
16
|
const temp_files_1 = require("./temp-files");
|
|
19
17
|
const upload_1 = require("./upload");
|
|
20
18
|
const validation_1 = require("./validation");
|
|
21
|
-
function extractVideoAttachments(repoDir) {
|
|
22
|
-
try {
|
|
23
|
-
const summaryPath = path_1.default.join(repoDir, "summary.json");
|
|
24
|
-
if (!fs_1.default.existsSync(summaryPath)) {
|
|
25
|
-
console.log("summary.json not found");
|
|
26
|
-
return [];
|
|
27
|
-
}
|
|
28
|
-
const summaryContent = JSON.parse(fs_1.default.readFileSync(summaryPath, "utf-8"));
|
|
29
|
-
const attachments = (0, utils_2.extractAttachmentsFromPlaywrightJSONReport)(summaryContent, "temp test");
|
|
30
|
-
const videoPaths = attachments
|
|
31
|
-
.filter((attachment) => attachment.contentType === "video/webm")
|
|
32
|
-
.map((attachment) => attachment.path);
|
|
33
|
-
return videoPaths;
|
|
34
|
-
}
|
|
35
|
-
catch (error) {
|
|
36
|
-
console.warn("Error processing summary.json:", error);
|
|
37
|
-
return [];
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
19
|
async function runRecorder({ name }) {
|
|
41
20
|
console.log(`Recording for test name: ${name}`);
|
|
42
21
|
const repoDir = process.cwd();
|
|
22
|
+
let repoName = "";
|
|
43
23
|
try {
|
|
44
|
-
await (0, validation_1.
|
|
24
|
+
repoName = await (0, validation_1.validatePackageJson)(repoDir);
|
|
45
25
|
}
|
|
46
26
|
catch (error) {
|
|
47
27
|
console.error("Error running recorder:", error);
|
|
48
28
|
process.exit(1);
|
|
49
29
|
}
|
|
50
|
-
if (!process.env.EMPIRICALRUN_API_KEY) {
|
|
51
|
-
console.error("EMPIRICALRUN_API_KEY is not set. Please set it in your environment variables.");
|
|
52
|
-
process.exit(1);
|
|
53
|
-
}
|
|
54
30
|
try {
|
|
55
31
|
// Prepare playwright for codegen
|
|
56
32
|
console.log("[generateTestWithBrowserAgent] Preparing playwright for codegen");
|
|
@@ -59,7 +35,7 @@ async function runRecorder({ name }) {
|
|
|
59
35
|
catch (err) {
|
|
60
36
|
console.warn("[generateTestWithBrowserAgent] Error preparing playwright for codegen", err);
|
|
61
37
|
}
|
|
62
|
-
const envVariables = await (0,
|
|
38
|
+
const envVariables = await (0, env_variables_1.fetchEnvironmentVariables)(repoName);
|
|
63
39
|
await (0, temp_files_1.createTempTestFile)();
|
|
64
40
|
const absFilePath = path_1.default.join(process.cwd(), "tests", "temp-test.spec.ts");
|
|
65
41
|
await (0, utils_1.addImportForMethod)(absFilePath, "recordTest");
|
|
@@ -84,7 +60,7 @@ async function runRecorder({ name }) {
|
|
|
84
60
|
IPC_FILE_SERVICE_PORT: availablePort.toString(),
|
|
85
61
|
},
|
|
86
62
|
});
|
|
87
|
-
const videoPaths = extractVideoAttachments(repoDir);
|
|
63
|
+
const videoPaths = (0, upload_1.extractVideoAttachments)(repoDir);
|
|
88
64
|
let attachments = [];
|
|
89
65
|
if (videoPaths.length === 0) {
|
|
90
66
|
console.warn("No video attachments found for temp test");
|
|
@@ -101,6 +77,7 @@ async function runRecorder({ name }) {
|
|
|
101
77
|
await fileServer.stop();
|
|
102
78
|
const finalCode = await (0, display_1.displayResultsAndConfirm)(name, codegenResult);
|
|
103
79
|
await (0, request_1.sendToDashboardAsRequest)({
|
|
80
|
+
repoName,
|
|
104
81
|
testName: name,
|
|
105
82
|
codegenResult: finalCode,
|
|
106
83
|
attachments,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export declare function sendToDashboardAsRequest({ testName, codegenResult, attachments, }: {
|
|
1
|
+
export declare function sendToDashboardAsRequest({ repoName, testName, codegenResult, attachments, }: {
|
|
2
|
+
repoName: string;
|
|
2
3
|
testName: string;
|
|
3
4
|
codegenResult: string;
|
|
4
5
|
attachments: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/recorder/request.ts"],"names":[],"mappings":"
|
|
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"}
|
package/dist/recorder/request.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.sendToDashboardAsRequest = sendToDashboardAsRequest;
|
|
4
|
-
const
|
|
4
|
+
const api_client_1 = require("../auth/api-client");
|
|
5
5
|
const title = (name) => `Add a test: ${name}`;
|
|
6
6
|
function description(codegenResult, attachments) {
|
|
7
7
|
return [
|
|
@@ -12,42 +12,37 @@ function description(codegenResult, attachments) {
|
|
|
12
12
|
...attachments,
|
|
13
13
|
].join("\n\n");
|
|
14
14
|
}
|
|
15
|
-
async function sendToDashboardAsRequest({ testName, codegenResult, attachments, }) {
|
|
15
|
+
async function sendToDashboardAsRequest({ repoName, testName, codegenResult, attachments, }) {
|
|
16
16
|
return createRequest({
|
|
17
|
+
repoName,
|
|
17
18
|
title: title(testName),
|
|
18
19
|
description: description(codegenResult, attachments),
|
|
19
20
|
});
|
|
20
21
|
}
|
|
21
|
-
async function createRequest({ title, description, }) {
|
|
22
|
-
if (!DASHBOARD_DOMAIN) {
|
|
23
|
-
console.warn("DASHBOARD_DOMAIN not set, skipping request creation");
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
if (!process.env.EMPIRICALRUN_API_KEY) {
|
|
27
|
-
console.warn("EMPIRICALRUN_API_KEY not set, skipping request creation");
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
22
|
+
async function createRequest({ repoName, title, description, }) {
|
|
30
23
|
try {
|
|
24
|
+
// TODO: Fix the source and sourceIdentifier
|
|
31
25
|
const source = "cli";
|
|
32
26
|
const sourceIdentifier = "random-string";
|
|
33
|
-
const response = await
|
|
27
|
+
const response = await api_client_1.apiClient.request("/api/requests", {
|
|
34
28
|
method: "POST",
|
|
35
|
-
headers: {
|
|
36
|
-
"Content-Type": "application/json",
|
|
37
|
-
Authorization: `Bearer ${process.env.EMPIRICALRUN_API_KEY}`,
|
|
38
|
-
},
|
|
39
29
|
body: JSON.stringify({
|
|
40
30
|
source,
|
|
41
31
|
source_identifier: sourceIdentifier,
|
|
42
32
|
title,
|
|
43
33
|
description,
|
|
34
|
+
project_repo_name: repoName,
|
|
44
35
|
}),
|
|
45
36
|
});
|
|
46
37
|
if (!response.ok) {
|
|
47
|
-
|
|
38
|
+
const errorMessage = await response.text();
|
|
39
|
+
throw new Error(`Failed to create request: ${errorMessage}`);
|
|
48
40
|
}
|
|
49
41
|
const data = await response.json();
|
|
50
|
-
|
|
42
|
+
const dashboardDomain = process.env.DASHBOARD_DOMAIN || "https://dash.empirical.run";
|
|
43
|
+
const requestUrl = `${dashboardDomain}/${repoName}/requests/${data.data.request.id}`;
|
|
44
|
+
// console.log("Request created successfully:", data);
|
|
45
|
+
console.log(`View request: ${requestUrl}`);
|
|
51
46
|
}
|
|
52
47
|
catch (error) {
|
|
53
48
|
console.error("Failed to create request:", error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/recorder/upload.ts"],"names":[],"mappings":"
|
|
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"}
|
package/dist/recorder/upload.js
CHANGED
|
@@ -3,16 +3,38 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.extractVideoAttachments = extractVideoAttachments;
|
|
6
7
|
exports.uploadVideosWithSpinner = uploadVideosWithSpinner;
|
|
7
8
|
const fs_1 = __importDefault(require("fs"));
|
|
8
9
|
const ora_1 = __importDefault(require("ora"));
|
|
9
10
|
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const utils_1 = require("../artifacts/utils");
|
|
12
|
+
const api_client_1 = require("../auth/api-client");
|
|
10
13
|
const slug_1 = require("../utils/slug");
|
|
11
14
|
const ASSETS_PRODUCTION_BUCKET = "empirical-assets-production";
|
|
12
15
|
const BUCKET_DOMAINS = {
|
|
13
16
|
"empirical-assets-staging": "assets-staging.empirical.run",
|
|
14
17
|
"empirical-assets-production": "assets.empirical.run",
|
|
15
18
|
};
|
|
19
|
+
function extractVideoAttachments(repoDir) {
|
|
20
|
+
try {
|
|
21
|
+
const summaryPath = path_1.default.join(repoDir, "summary.json");
|
|
22
|
+
if (!fs_1.default.existsSync(summaryPath)) {
|
|
23
|
+
console.log("summary.json not found");
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
const summaryContent = JSON.parse(fs_1.default.readFileSync(summaryPath, "utf-8"));
|
|
27
|
+
const attachments = (0, utils_1.extractAttachmentsFromPlaywrightJSONReport)(summaryContent, "temp test");
|
|
28
|
+
const videoPaths = attachments
|
|
29
|
+
.filter((attachment) => attachment.contentType === "video/webm")
|
|
30
|
+
.map((attachment) => attachment.path);
|
|
31
|
+
return videoPaths;
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
console.warn("Error processing summary.json:", error);
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
16
38
|
function buildVideoUrl(localPath, directory, bucket) {
|
|
17
39
|
const domain = BUCKET_DOMAINS[bucket];
|
|
18
40
|
const fileName = path_1.default.basename(localPath);
|
|
@@ -22,12 +44,6 @@ async function uploadVideos(videoPaths, testSlug) {
|
|
|
22
44
|
if (videoPaths.length === 0) {
|
|
23
45
|
return null;
|
|
24
46
|
}
|
|
25
|
-
const DASHBOARD_DOMAIN = process.env.DASHBOARD_DOMAIN || "https://dash.empirical.run";
|
|
26
|
-
const API_KEY = process.env.EMPIRICALRUN_API_KEY;
|
|
27
|
-
if (!API_KEY) {
|
|
28
|
-
console.warn("EMPIRICALRUN_API_KEY not set, skipping video upload");
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
47
|
const uploadDestinationDir = `recorder-uploads/${testSlug}`;
|
|
32
48
|
const bucket = ASSETS_PRODUCTION_BUCKET;
|
|
33
49
|
try {
|
|
@@ -42,11 +58,8 @@ async function uploadVideos(videoPaths, testSlug) {
|
|
|
42
58
|
formData.append("files", blob, fileName);
|
|
43
59
|
}
|
|
44
60
|
}
|
|
45
|
-
const response = await
|
|
61
|
+
const response = await api_client_1.apiClient.request("/api/upload", {
|
|
46
62
|
method: "POST",
|
|
47
|
-
headers: {
|
|
48
|
-
Authorization: `Bearer ${API_KEY}`,
|
|
49
|
-
},
|
|
50
63
|
body: formData,
|
|
51
64
|
});
|
|
52
65
|
if (!response.ok) {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare function
|
|
1
|
+
export declare function validatePackageJson(repoDir: string): Promise<any>;
|
|
2
2
|
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/recorder/validation.ts"],"names":[],"mappings":"AAGA,wBAAsB,
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/recorder/validation.ts"],"names":[],"mappings":"AAGA,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,gBAyBxD"}
|
|
@@ -3,16 +3,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.validatePackageJson = validatePackageJson;
|
|
7
7
|
const fs_1 = __importDefault(require("fs"));
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
|
-
async function
|
|
10
|
-
// Check if package.json exists
|
|
9
|
+
async function validatePackageJson(repoDir) {
|
|
11
10
|
const packageJsonPath = path_1.default.join(repoDir, "package.json");
|
|
12
11
|
if (!fs_1.default.existsSync(packageJsonPath)) {
|
|
13
12
|
throw new Error("package.json not found in the repository");
|
|
14
13
|
}
|
|
15
|
-
// Check if playwright is installed
|
|
16
14
|
const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, "utf8"));
|
|
17
15
|
const hasPlaywright = (packageJson.dependencies &&
|
|
18
16
|
packageJson.dependencies["@playwright/test"]) ||
|
|
@@ -21,4 +19,11 @@ async function validate(repoDir) {
|
|
|
21
19
|
if (!hasPlaywright) {
|
|
22
20
|
throw new Error("Playwright is not installed. Please install @playwright/test");
|
|
23
21
|
}
|
|
22
|
+
const repoName = packageJson.name;
|
|
23
|
+
if (repoName && repoName.endsWith("-tests")) {
|
|
24
|
+
return repoName;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
throw new Error(`Invalid repo name in package.json: ${repoName}`);
|
|
28
|
+
}
|
|
24
29
|
}
|
package/package.json
CHANGED
package/tsconfig.tsbuildinfo
CHANGED
|
@@ -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/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/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"}
|