@empiricalrun/test-gen 0.46.0 → 0.46.2
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 +15 -0
- package/dist/agent/browsing/run.d.ts.map +1 -1
- package/dist/agent/browsing/run.js +0 -25
- package/dist/agent/master/browser-tests/index.spec.js +43 -0
- package/dist/agent/master/element-annotation.d.ts.map +1 -1
- package/dist/agent/master/element-annotation.js +20 -5
- package/dist/bin/index.d.ts +1 -1
- package/dist/bin/index.d.ts.map +1 -1
- package/dist/bin/index.js +59 -93
- package/dist/bin/utils/index.d.ts +0 -2
- package/dist/bin/utils/index.d.ts.map +1 -1
- package/dist/bin/utils/index.js +1 -3
- package/dist/test-build/index.d.ts.map +1 -1
- package/dist/test-build/index.js +0 -25
- package/dist/utils/exec.d.ts +0 -2
- package/dist/utils/exec.d.ts.map +1 -1
- package/dist/utils/exec.js +32 -65
- package/package.json +4 -5
- package/playwright.config.ts +1 -1
- package/dist/initSentry.d.ts +0 -2
- package/dist/initSentry.d.ts.map +0 -1
- package/dist/initSentry.js +0 -37
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @empiricalrun/test-gen
|
|
2
2
|
|
|
3
|
+
## 0.46.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 9770fd6: test: fill action with multiple pages
|
|
8
|
+
- c723f61: fix: auto fix didnt work
|
|
9
|
+
- e6d6174: chore: remove sentry from worker, service and test-gen
|
|
10
|
+
|
|
11
|
+
## 0.46.1
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- 0aa2054: test: add failing test for annotation enrichment for iframes
|
|
16
|
+
- 21f5534: fix: enrich annotations inside iframes
|
|
17
|
+
|
|
3
18
|
## 0.46.0
|
|
4
19
|
|
|
5
20
|
### Minor Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/run.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/run.ts"],"names":[],"mappings":"AAkBA,KAAK,iBAAiB,GAAG;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAsB,6BAA6B,CAAC,EAClD,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,OAAO,GACR,EAAE,iBAAiB,iBA6EnB"}
|
|
@@ -1,33 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
4
|
};
|
|
28
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
6
|
exports.generateTestsUsingMasterAgent = void 0;
|
|
30
|
-
const Sentry = __importStar(require("@sentry/node"));
|
|
31
7
|
const detect_port_1 = __importDefault(require("detect-port"));
|
|
32
8
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
33
9
|
const web_1 = require("../../bin/utils/platform/web");
|
|
@@ -80,7 +56,6 @@ async function generateTestsUsingMasterAgent({ testFilePath, filePathToUpdate, p
|
|
|
80
56
|
PAGE_VAR_NAME: pageVar || "page",
|
|
81
57
|
DISPLAY: ":99",
|
|
82
58
|
},
|
|
83
|
-
span: Sentry.getActiveSpan(),
|
|
84
59
|
});
|
|
85
60
|
}
|
|
86
61
|
catch (e) {
|
|
@@ -7,6 +7,8 @@ const test_1 = require("@playwright/test");
|
|
|
7
7
|
const fs_1 = __importDefault(require("fs"));
|
|
8
8
|
const http_server_1 = __importDefault(require("http-server"));
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const utils_1 = require("../../browsing/utils");
|
|
11
|
+
const element_annotation_1 = require("../element-annotation");
|
|
10
12
|
const run_1 = require("../run");
|
|
11
13
|
let server;
|
|
12
14
|
let PORT = 2345;
|
|
@@ -70,3 +72,44 @@ test_1.test.afterAll(() => {
|
|
|
70
72
|
(0, test_1.expect)(icons.length).toBe(4); // 1 for each unique icon
|
|
71
73
|
fs_1.default.unlinkSync(iconsRegistryFile);
|
|
72
74
|
});
|
|
75
|
+
(0, test_1.test)("annotate and enrich annotations correctly", async ({ page }) => {
|
|
76
|
+
await (0, utils_1.injectPwLocatorGenerator)(page);
|
|
77
|
+
await page.goto(`http://localhost:${PORT}/iframe-elements.html`);
|
|
78
|
+
const { annotationKeys: keys } = await (0, element_annotation_1.getAnnotationKeys)({
|
|
79
|
+
page,
|
|
80
|
+
preference: {
|
|
81
|
+
actionType: "all",
|
|
82
|
+
},
|
|
83
|
+
options: {},
|
|
84
|
+
});
|
|
85
|
+
console.log(keys);
|
|
86
|
+
(0, test_1.expect)(keys.length).toBe(6);
|
|
87
|
+
// 2 icons: 1 in main frame, 1 in iframe
|
|
88
|
+
(0, test_1.expect)(keys.filter((k) => k.text.includes("icon") && k.text.includes("close"))
|
|
89
|
+
.length).toBe(2);
|
|
90
|
+
// 2 text inputs: 1 in main frame, 1 in iframe
|
|
91
|
+
(0, test_1.expect)(keys.filter((k) => k.text.includes("Enter your name")).length).toBe(2);
|
|
92
|
+
// 2 clickable divs: 1 in main frame, 1 in iframe
|
|
93
|
+
(0, test_1.expect)(keys.filter((k) => k.text.includes("Lorem Ipsum")).length).toBe(2);
|
|
94
|
+
});
|
|
95
|
+
(0, test_1.test)("fill action with multiple pages", async ({ context }) => {
|
|
96
|
+
const page1 = await context.newPage();
|
|
97
|
+
const page2 = await context.newPage();
|
|
98
|
+
const response = await (0, run_1.createTestUsingMasterAgent)({
|
|
99
|
+
task: `goto empirical.run on page1 and goto google.com in page2. Enter text empirical on page2 and click on search.`,
|
|
100
|
+
page: page2,
|
|
101
|
+
options: {},
|
|
102
|
+
scopeVars: {
|
|
103
|
+
context,
|
|
104
|
+
page1,
|
|
105
|
+
page2,
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
(0, test_1.expect)(response.code).toBeTruthy();
|
|
109
|
+
console.log(response.code);
|
|
110
|
+
const lines = response.code.split("\n");
|
|
111
|
+
(0, test_1.expect)(lines.find((l) => l.match(/^await page1\.goto(.+)empirical\.run/))).toBeTruthy();
|
|
112
|
+
(0, test_1.expect)(lines.find((l) => l.match(/^await page2\.goto(.+)google\.com/))).toBeTruthy();
|
|
113
|
+
(0, test_1.expect)(lines.find((l) => l.match(/^await page2(.+)fill(.+)empirical/))).toBeTruthy();
|
|
114
|
+
(0, test_1.expect)(lines.find((l) => l.match(/^await page2(.+)click/))).toBeTruthy();
|
|
115
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"element-annotation.d.ts","sourceRoot":"","sources":["../../../src/agent/master/element-annotation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,GAAG,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAQlC,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AA2DjD,wBAAsB,oBAAoB,CAAC,EACzC,kBAAkB,EAClB,WAAW,EACX,mBAAmB,EACnB,KAAK,EACL,GAAG,EACH,OAAO,EACP,UAAU,GACX,EAAE;IACD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,UAAU,EAAE,oBAAoB,CAAC;CAClC,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA8C9B;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,UAAU,EACN,KAAK,GACL,UAAU,CAAC,IAAI,GACf,UAAU,CAAC,WAAW,GACtB,UAAU,CAAC,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC,CAAC;AAgBF,wBAAsB,iBAAiB,CAAC,EACtC,IAAI,EACJ,UAAU,EACV,OAAO,EACP,KAAK,GACN,EAAE;IACD,IAAI,EAAE,IAAI,CAAC;IACX,UAAU,EAAE,oBAAoB,CAAC;IACjC,OAAO,EAAE,oBAAoB,CAAC;IAC9B,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,GAAG,OAAO,CAAC;IACV,cAAc,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACtD,gBAAgB,EAAE,MAAM,CAAC;IACzB,uBAAuB,EAAE,MAAM,CAAC;CACjC,CAAC,
|
|
1
|
+
{"version":3,"file":"element-annotation.d.ts","sourceRoot":"","sources":["../../../src/agent/master/element-annotation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,GAAG,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAQlC,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AA2DjD,wBAAsB,oBAAoB,CAAC,EACzC,kBAAkB,EAClB,WAAW,EACX,mBAAmB,EACnB,KAAK,EACL,GAAG,EACH,OAAO,EACP,UAAU,GACX,EAAE;IACD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,UAAU,EAAE,oBAAoB,CAAC;CAClC,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA8C9B;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,UAAU,EACN,KAAK,GACL,UAAU,CAAC,IAAI,GACf,UAAU,CAAC,WAAW,GACtB,UAAU,CAAC,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC,CAAC;AAgBF,wBAAsB,iBAAiB,CAAC,EACtC,IAAI,EACJ,UAAU,EACV,OAAO,EACP,KAAK,GACN,EAAE;IACD,IAAI,EAAE,IAAI,CAAC;IACX,UAAU,EAAE,oBAAoB,CAAC;IACjC,OAAO,EAAE,oBAAoB,CAAC;IAC9B,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,GAAG,OAAO,CAAC;IACV,cAAc,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACtD,gBAAgB,EAAE,MAAM,CAAC;IACzB,uBAAuB,EAAE,MAAM,CAAC;CACjC,CAAC,CAoFD"}
|
|
@@ -111,15 +111,30 @@ async function getAnnotationKeys({ page, preference, options, trace, }) {
|
|
|
111
111
|
const annotations = Object.entries(
|
|
112
112
|
// @ts-ignore
|
|
113
113
|
window.annotationInstance.annotations).map(([key, value]) => {
|
|
114
|
+
// Helper function to safely get text content
|
|
115
|
+
const getTextContent = (node) => {
|
|
116
|
+
try {
|
|
117
|
+
return node?.innerText?.trim() || null;
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
// Helper function to safely get placeholder
|
|
124
|
+
const getPlaceholder = (node) => {
|
|
125
|
+
try {
|
|
126
|
+
return node?.placeholder?.trim() || null;
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
};
|
|
114
132
|
return {
|
|
115
133
|
elementID: key,
|
|
116
|
-
innerText: value.node
|
|
134
|
+
innerText: getTextContent(value.node),
|
|
117
135
|
innerHTML: value.node.innerHTML,
|
|
118
136
|
outerHTML: value.node.outerHTML,
|
|
119
|
-
placeholder: value.node
|
|
120
|
-
value.node instanceof HTMLTextAreaElement
|
|
121
|
-
? value.node.placeholder
|
|
122
|
-
: null,
|
|
137
|
+
placeholder: getPlaceholder(value.node),
|
|
123
138
|
};
|
|
124
139
|
});
|
|
125
140
|
const fullPageHTML = document.documentElement.outerHTML;
|
package/dist/bin/index.d.ts
CHANGED
package/dist/bin/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bin/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bin/index.ts"],"names":[],"mappings":""}
|
package/dist/bin/index.js
CHANGED
|
@@ -1,35 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
-
if (k2 === undefined) k2 = k;
|
|
5
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
-
}
|
|
9
|
-
Object.defineProperty(o, k2, desc);
|
|
10
|
-
}) : (function(o, m, k, k2) {
|
|
11
|
-
if (k2 === undefined) k2 = k;
|
|
12
|
-
o[k2] = m[k];
|
|
13
|
-
}));
|
|
14
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
-
}) : function(o, v) {
|
|
17
|
-
o["default"] = v;
|
|
18
|
-
});
|
|
19
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
20
|
-
if (mod && mod.__esModule) return mod;
|
|
21
|
-
var result = {};
|
|
22
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
23
|
-
__setModuleDefault(result, mod);
|
|
24
|
-
return result;
|
|
25
|
-
};
|
|
26
3
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
27
4
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
28
5
|
};
|
|
29
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
-
require("../initSentry");
|
|
31
7
|
const llm_1 = require("@empiricalrun/llm");
|
|
32
|
-
const Sentry = __importStar(require("@sentry/node"));
|
|
33
8
|
const commander_1 = require("commander");
|
|
34
9
|
const dotenv_1 = __importDefault(require("dotenv"));
|
|
35
10
|
const run_1 = require("../agent/browsing/run");
|
|
@@ -51,7 +26,6 @@ dotenv_1.default.config({
|
|
|
51
26
|
});
|
|
52
27
|
const flushEvents = async () => {
|
|
53
28
|
await (0, llm_1.flushAllTraces)();
|
|
54
|
-
await Sentry.flush();
|
|
55
29
|
};
|
|
56
30
|
process.on("beforeExit", async () => await flushEvents());
|
|
57
31
|
process.on("exit", async () => await flushEvents());
|
|
@@ -64,7 +38,7 @@ async function resolveAgentUsingTask({ testCase, trace, }) {
|
|
|
64
38
|
});
|
|
65
39
|
return response;
|
|
66
40
|
}
|
|
67
|
-
async function runAgent(testGenConfig, testGenToken
|
|
41
|
+
async function runAgent(testGenConfig, testGenToken) {
|
|
68
42
|
const logger = new logger_1.CustomLogger();
|
|
69
43
|
const { specPath, testCase } = testGenConfig;
|
|
70
44
|
if (process.env.LOG_URL) {
|
|
@@ -72,7 +46,6 @@ async function runAgent(testGenConfig, testGenToken, span) {
|
|
|
72
46
|
void new reporter_1.TestGenUpdatesReporter().sendLogUrl(process.env.LOG_URL);
|
|
73
47
|
}
|
|
74
48
|
catch (e) {
|
|
75
|
-
span?.recordException(e);
|
|
76
49
|
console.warn("Failed to send log url to test gen update", e);
|
|
77
50
|
}
|
|
78
51
|
}
|
|
@@ -120,7 +93,7 @@ async function runAgent(testGenConfig, testGenToken, span) {
|
|
|
120
93
|
if (testGenConfig.testErrorDiagnosis &&
|
|
121
94
|
testGenConfig.testErrorDiagnosis.failingLine &&
|
|
122
95
|
// TODO: fix this hardcoding of user prompt - ideally its an auto fix intent
|
|
123
|
-
testCase.steps[0] == "
|
|
96
|
+
testCase.steps[0]?.toLowerCase().trim() == "can you please fix the test") {
|
|
124
97
|
const { task: updatedTask } = await (0, diagnosis_agent_1.createTaskUsingFailureDiagnosis)({
|
|
125
98
|
options: testGenConfig.options,
|
|
126
99
|
trace,
|
|
@@ -178,69 +151,62 @@ async function runAgent(testGenConfig, testGenToken, span) {
|
|
|
178
151
|
return agent;
|
|
179
152
|
}
|
|
180
153
|
(async function main() {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
testSessionId: testGenConfig.options?.metadata.testSessionId,
|
|
202
|
-
generationId: testGenConfig.options?.metadata.generationId,
|
|
203
|
-
});
|
|
204
|
-
(0, session_1.setSessionDetails)({
|
|
205
|
-
testCaseId: testGenConfig.testCase.id,
|
|
206
|
-
sessionId: testGenConfig.options?.metadata.testSessionId,
|
|
207
|
-
generationId: testGenConfig.options?.metadata.generationId,
|
|
208
|
-
projectRepoName: testGenConfig.options?.metadata.projectRepoName,
|
|
209
|
-
});
|
|
210
|
-
let testGenFailed = false;
|
|
211
|
-
let agentUsed;
|
|
212
|
-
try {
|
|
213
|
-
// download the build if it exists
|
|
214
|
-
await (0, test_build_1.downloadBuild)(testGenConfig.build || {});
|
|
215
|
-
agentUsed = await runAgent(testGenConfig, testGenToken);
|
|
216
|
-
}
|
|
217
|
-
catch (e) {
|
|
218
|
-
span.recordException(e);
|
|
219
|
-
Sentry.captureException(e);
|
|
220
|
-
testGenFailed = true;
|
|
221
|
-
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);
|
|
222
|
-
}
|
|
223
|
-
if (agentUsed &&
|
|
224
|
-
agentUsed !== "code" &&
|
|
225
|
-
agentUsed !== "plan" &&
|
|
226
|
-
testGenConfig.testCase.name &&
|
|
227
|
-
testGenConfig.options) {
|
|
228
|
-
await new reporter_1.TestGenUpdatesReporter().reportGenAssets({
|
|
229
|
-
projectRepoName: testGenConfig.options.metadata.projectRepoName,
|
|
230
|
-
testName: testGenConfig.testCase.name,
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
// TODO: move these reporters to a better lifecycle
|
|
234
|
-
await (0, llm_1.flushAllTraces)();
|
|
235
|
-
await (0, logger_1.waitForLogsToFlush)();
|
|
236
|
-
await (0, session_1.endSession)();
|
|
237
|
-
span.end();
|
|
238
|
-
if (testGenFailed) {
|
|
239
|
-
process.exit(1);
|
|
240
|
-
}
|
|
241
|
-
else {
|
|
242
|
-
process.exit(0);
|
|
243
|
-
}
|
|
244
|
-
});
|
|
154
|
+
const program = new commander_1.Command();
|
|
155
|
+
program
|
|
156
|
+
.option("--token <token>", "Test generation token")
|
|
157
|
+
.option("--name <test-name>", "Name of the test case")
|
|
158
|
+
.option("--prompt <prompt>", "Prompt for the test case")
|
|
159
|
+
.option("--file <test-file>", "File path of the test case (inside tests dir)")
|
|
160
|
+
.option("--suites <suites>", "Comma separated list of describe blocks")
|
|
161
|
+
.parse(process.argv);
|
|
162
|
+
const options = program.opts();
|
|
163
|
+
(0, utils_2.validateCliOptions)(options);
|
|
164
|
+
const testGenConfig = options.token
|
|
165
|
+
? (0, scenarios_1.loadTestConfigs)(options.token)
|
|
166
|
+
: (0, scenarios_1.buildTestConfigFromOptions)(options);
|
|
167
|
+
const testGenToken = options.token
|
|
168
|
+
? options.token
|
|
169
|
+
: (0, scenarios_1.buildTokenFromOptions)(options);
|
|
170
|
+
(0, reporter_1.setReporterConfig)({
|
|
171
|
+
projectRepoName: testGenConfig.options?.metadata.projectRepoName,
|
|
172
|
+
testSessionId: testGenConfig.options?.metadata.testSessionId,
|
|
173
|
+
generationId: testGenConfig.options?.metadata.generationId,
|
|
245
174
|
});
|
|
175
|
+
(0, session_1.setSessionDetails)({
|
|
176
|
+
testCaseId: testGenConfig.testCase.id,
|
|
177
|
+
sessionId: testGenConfig.options?.metadata.testSessionId,
|
|
178
|
+
generationId: testGenConfig.options?.metadata.generationId,
|
|
179
|
+
projectRepoName: testGenConfig.options?.metadata.projectRepoName,
|
|
180
|
+
});
|
|
181
|
+
let testGenFailed = false;
|
|
182
|
+
let agentUsed;
|
|
183
|
+
try {
|
|
184
|
+
// download the build if it exists
|
|
185
|
+
await (0, test_build_1.downloadBuild)(testGenConfig.build || {});
|
|
186
|
+
agentUsed = await runAgent(testGenConfig, testGenToken);
|
|
187
|
+
}
|
|
188
|
+
catch (e) {
|
|
189
|
+
testGenFailed = true;
|
|
190
|
+
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);
|
|
191
|
+
}
|
|
192
|
+
if (agentUsed &&
|
|
193
|
+
agentUsed !== "code" &&
|
|
194
|
+
agentUsed !== "plan" &&
|
|
195
|
+
testGenConfig.testCase.name &&
|
|
196
|
+
testGenConfig.options) {
|
|
197
|
+
await new reporter_1.TestGenUpdatesReporter().reportGenAssets({
|
|
198
|
+
projectRepoName: testGenConfig.options.metadata.projectRepoName,
|
|
199
|
+
testName: testGenConfig.testCase.name,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
// TODO: move these reporters to a better lifecycle
|
|
203
|
+
await (0, llm_1.flushAllTraces)();
|
|
204
|
+
await (0, logger_1.waitForLogsToFlush)();
|
|
205
|
+
await (0, session_1.endSession)();
|
|
206
|
+
if (testGenFailed) {
|
|
207
|
+
process.exit(1);
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
process.exit(0);
|
|
211
|
+
}
|
|
246
212
|
})();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bin/utils/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bin/utils/index.ts"],"names":[],"mappings":"AAAA,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;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAS5D"}
|
package/dist/bin/utils/index.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.validateCliOptions =
|
|
4
|
-
exports.sentryTrace = process.env.SENTRY_TRACE;
|
|
5
|
-
exports.baggage = process.env.SENTRY_BAGGAGE;
|
|
3
|
+
exports.validateCliOptions = void 0;
|
|
6
4
|
function validateCliOptions(options) {
|
|
7
5
|
const hasToken = !!options.token;
|
|
8
6
|
const hasNameAndFile = !!options.name && !!options.file && !!options.prompt;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test-build/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test-build/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAUnD;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAY/D"}
|
package/dist/test-build/index.js
CHANGED
|
@@ -1,33 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
4
|
};
|
|
28
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
6
|
exports.downloadBuild = void 0;
|
|
30
|
-
const Sentry = __importStar(require("@sentry/node"));
|
|
31
7
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
32
8
|
const logger_1 = require("../bin/logger");
|
|
33
9
|
const exec_1 = require("../utils/exec");
|
|
@@ -48,7 +24,6 @@ async function downloadBuild(build) {
|
|
|
48
24
|
logger.log(`Downloading build from ${build.url}`);
|
|
49
25
|
await (0, exec_1.cmd)(`npm run download ${build.url}`.split(" "), {
|
|
50
26
|
env: { ...Object(process.env) },
|
|
51
|
-
span: Sentry.getActiveSpan(),
|
|
52
27
|
});
|
|
53
28
|
}
|
|
54
29
|
}
|
package/dist/utils/exec.d.ts
CHANGED
package/dist/utils/exec.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"AAGA,wBAAsB,GAAG,CACvB,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GACxC,OAAO,CAAC,MAAM,CAAC,CAuCjB"}
|
package/dist/utils/exec.js
CHANGED
|
@@ -1,77 +1,44 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
4
|
};
|
|
28
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
6
|
exports.cmd = void 0;
|
|
30
|
-
const Sentry = __importStar(require("@sentry/node"));
|
|
31
7
|
const child_process_1 = require("child_process");
|
|
32
8
|
const process_1 = __importDefault(require("process"));
|
|
33
|
-
const utils_1 = require("../bin/utils");
|
|
34
9
|
async function cmd(command, options) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
Sentry.captureException(new Error(errorMessage));
|
|
68
|
-
rejectFunc(new Error(errorMessage));
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
resolveFunc(code ?? 1);
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
});
|
|
10
|
+
let errorLogs = [];
|
|
11
|
+
return new Promise((resolveFunc, rejectFunc) => {
|
|
12
|
+
if (!command[0]) {
|
|
13
|
+
rejectFunc(new Error("Command cannot be empty"));
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
let p = (0, child_process_1.spawn)(command[0], command.slice(1), {
|
|
17
|
+
env: { ...process_1.default.env, ...options.env },
|
|
18
|
+
});
|
|
19
|
+
p.stdout.on("data", (x) => {
|
|
20
|
+
const log = x.toString();
|
|
21
|
+
if (log.includes("Error")) {
|
|
22
|
+
errorLogs.push(log);
|
|
23
|
+
}
|
|
24
|
+
process_1.default.stdout.write(log);
|
|
25
|
+
});
|
|
26
|
+
p.stderr.on("data", (x) => {
|
|
27
|
+
const log = x.toString();
|
|
28
|
+
process_1.default.stderr.write(log);
|
|
29
|
+
errorLogs.push(log);
|
|
30
|
+
});
|
|
31
|
+
p.on("error", async (err) => {
|
|
32
|
+
rejectFunc(err);
|
|
33
|
+
});
|
|
34
|
+
p.on("exit", async (code) => {
|
|
35
|
+
if (code !== 0) {
|
|
36
|
+
const errorMessage = errorLogs.slice(-3).join("\n");
|
|
37
|
+
rejectFunc(new Error(errorMessage));
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
resolveFunc(code ?? 1);
|
|
41
|
+
}
|
|
75
42
|
});
|
|
76
43
|
});
|
|
77
44
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@empiricalrun/test-gen",
|
|
3
|
-
"version": "0.46.
|
|
3
|
+
"version": "0.46.2",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"registry": "https://registry.npmjs.org/",
|
|
6
6
|
"access": "public"
|
|
@@ -47,7 +47,6 @@
|
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@actions/core": "^1.10.1",
|
|
49
49
|
"@babel/parser": "^7.26.3",
|
|
50
|
-
"@sentry/node": "^8.54.0",
|
|
51
50
|
"@types/sanitize-html": "^2.11.0",
|
|
52
51
|
"commander": "^12.1.0",
|
|
53
52
|
"detect-port": "^1.6.1",
|
|
@@ -75,8 +74,8 @@
|
|
|
75
74
|
"tsx": "^4.16.2",
|
|
76
75
|
"typescript": "^5.3.3",
|
|
77
76
|
"@empiricalrun/llm": "^0.9.35",
|
|
78
|
-
"@empiricalrun/
|
|
79
|
-
"@empiricalrun/
|
|
77
|
+
"@empiricalrun/r2-uploader": "^0.3.8",
|
|
78
|
+
"@empiricalrun/reporter": "^0.23.1"
|
|
80
79
|
},
|
|
81
80
|
"devDependencies": {
|
|
82
81
|
"@playwright/test": "1.47.1",
|
|
@@ -92,7 +91,7 @@
|
|
|
92
91
|
"js-levenshtein": "^1.1.6",
|
|
93
92
|
"playwright": "1.47.1",
|
|
94
93
|
"ts-patch": "^3.3.0",
|
|
95
|
-
"@empiricalrun/shared-types": "0.0.
|
|
94
|
+
"@empiricalrun/shared-types": "0.0.5"
|
|
96
95
|
},
|
|
97
96
|
"scripts": {
|
|
98
97
|
"dev": "tspc --build --watch",
|
package/playwright.config.ts
CHANGED
package/dist/initSentry.d.ts
DELETED
package/dist/initSentry.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"initSentry.d.ts","sourceRoot":"","sources":["../src/initSentry.ts"],"names":[],"mappings":""}
|
package/dist/initSentry.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
const Sentry = __importStar(require("@sentry/node"));
|
|
27
|
-
Sentry.init({
|
|
28
|
-
enabled: process.env.NODE_ENV === "production",
|
|
29
|
-
dsn: "https://87e61b11ede1431d7156bcd26da997cc@o4506822020235264.ingest.us.sentry.io/4508806031015936",
|
|
30
|
-
tracesSampleRate: 1.0,
|
|
31
|
-
serverName: "test-gen",
|
|
32
|
-
debug: process.env.NODE_ENV === "development",
|
|
33
|
-
integrations: [Sentry.consoleIntegration(), Sentry.httpIntegration()],
|
|
34
|
-
clientReportFlushInterval: 2000,
|
|
35
|
-
shutdownTimeout: 5000,
|
|
36
|
-
enableTracing: true,
|
|
37
|
-
});
|