@empiricalrun/test-gen 0.38.11 → 0.38.15
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 +29 -0
- package/browser-injected-scripts/annotate-elements.js +3 -3
- package/dist/actions/skill.d.ts.map +1 -1
- package/dist/actions/skill.js +8 -4
- package/dist/agent/browsing/utils.js +5 -5
- package/dist/agent/codegen/fix-ts-errors.d.ts +2 -2
- package/dist/agent/codegen/fix-ts-errors.d.ts.map +1 -1
- package/dist/agent/codegen/fix-ts-errors.js +4 -4
- package/dist/agent/codegen/run.js +2 -2
- package/dist/agent/codegen/update-flow.d.ts +6 -1
- package/dist/agent/codegen/update-flow.d.ts.map +1 -1
- package/dist/agent/codegen/update-flow.js +15 -14
- package/dist/agent/master/run.d.ts +4 -1
- package/dist/agent/master/run.d.ts.map +1 -1
- package/dist/agent/master/run.js +16 -4
- package/dist/agent/master/with-hints.d.ts +4 -1
- package/dist/agent/master/with-hints.d.ts.map +1 -1
- package/dist/agent/master/with-hints.js +1 -1
- package/dist/agent/planner/run-time-planner.d.ts.map +1 -1
- package/dist/agent/planner/run-time-planner.js +8 -4
- package/dist/bin/utils/context.d.ts +1 -0
- package/dist/bin/utils/context.d.ts.map +1 -1
- package/dist/bin/utils/context.js +1 -0
- package/dist/bin/utils/fs/index.d.ts +1 -0
- package/dist/bin/utils/fs/index.d.ts.map +1 -1
- package/dist/bin/utils/fs/index.js +18 -1
- package/dist/bin/utils/platform/web/index.d.ts.map +1 -1
- package/dist/bin/utils/platform/web/index.js +14 -18
- package/dist/browser-injected-scripts/annotate-elements.js +3 -3
- package/dist/evals/update-scenario-agent.evals.d.ts.map +1 -1
- package/dist/evals/update-scenario-agent.evals.js +3 -5
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# @empiricalrun/test-gen
|
|
2
2
|
|
|
3
|
+
## 0.38.15
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 91ded8f: fix: incorrect annotations
|
|
8
|
+
|
|
9
|
+
## 0.38.14
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- bd5c945: fix: run update scenario prompts on claude
|
|
14
|
+
- 31f8805: fix: runtime planner calling out actions as done
|
|
15
|
+
- Updated dependencies [bd5c945]
|
|
16
|
+
- @empiricalrun/llm@0.9.26
|
|
17
|
+
|
|
18
|
+
## 0.38.13
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- babf00a: fix: updated check for instance element
|
|
23
|
+
|
|
24
|
+
## 0.38.12
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- 3739ba6: fix: userContext not getting imported in case of edit test
|
|
29
|
+
- 368a859: fix: skill wasn't used in case task didn't contain next action details
|
|
30
|
+
- 3d0185e: fix: reduce payload for fix ts error call
|
|
31
|
+
|
|
3
32
|
## 0.38.11
|
|
4
33
|
|
|
5
34
|
### Patch Changes
|
|
@@ -103,8 +103,8 @@ function annotateClickableElements(options = {}) {
|
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
// Check if an element is clickable
|
|
106
|
-
function isElementClickable(element) {
|
|
107
|
-
|
|
106
|
+
function isElementClickable(element, windowToAnnotate) {
|
|
107
|
+
if (!(element instanceof windowToAnnotate.Element)) return false;
|
|
108
108
|
|
|
109
109
|
const tagName = element.tagName.toLowerCase();
|
|
110
110
|
let isClickable = false;
|
|
@@ -380,7 +380,7 @@ function annotateClickableElements(options = {}) {
|
|
|
380
380
|
|
|
381
381
|
// Filter for clickable elements
|
|
382
382
|
const clickableElements = Array.from(windowToAnnotate.document.querySelectorAll("*")).filter((el) => {
|
|
383
|
-
const isClickable = isElementClickable(el);
|
|
383
|
+
const isClickable = isElementClickable(el, windowToAnnotate);
|
|
384
384
|
const isClickNotBlocked = isElementClickNotBlocked(el, windowToAnnotate);
|
|
385
385
|
return isClickable && isClickNotBlocked;
|
|
386
386
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../../src/actions/skill.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAGrD,eAAO,MAAM,WAAW,gBAAgB,CAAC;AAEzC,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,cAAM,cAAc;IACN,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,KAAK,EAAE;IAEnC,kBAAkB;IAIlB,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE;CAG7B;AAED,eAAO,MAAM,cAAc,gBAAyB,CAAC;AAErD,eAAO,MAAM,oBAAoB,EAAE,
|
|
1
|
+
{"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../../src/actions/skill.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAGrD,eAAO,MAAM,WAAW,gBAAgB,CAAC;AAEzC,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,cAAM,cAAc;IACN,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,KAAK,EAAE;IAEnC,kBAAkB;IAIlB,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE;CAG7B;AAED,eAAO,MAAM,cAAc,gBAAyB,CAAC;AAErD,eAAO,MAAM,oBAAoB,EAAE,yBAmHlC,CAAC"}
|
package/dist/actions/skill.js
CHANGED
|
@@ -27,7 +27,7 @@ const skillActionGenerator = (page, options) => {
|
|
|
27
27
|
const availableSkills = exports.testCaseSkills.getAvailableSkills();
|
|
28
28
|
return {
|
|
29
29
|
execute: async ({ args, trace }) => {
|
|
30
|
-
const skill = args
|
|
30
|
+
const { skill, action } = args;
|
|
31
31
|
const [skillDetails] = availableSkills.filter((skillDetails) => skillDetails.testStep === skill);
|
|
32
32
|
if (!skillDetails) {
|
|
33
33
|
throw new Error(`No skill found for skill: ${skill}`);
|
|
@@ -39,7 +39,7 @@ const skillActionGenerator = (page, options) => {
|
|
|
39
39
|
const skillFile = await promises_1.default.readFile(skillFilePath, "utf-8");
|
|
40
40
|
const imports = Object.keys(module);
|
|
41
41
|
const code = await (0, use_skill_1.generateSkillUsageCode)({
|
|
42
|
-
task:
|
|
42
|
+
task: action,
|
|
43
43
|
sampleUsageMethod: skillDetails.usageExample,
|
|
44
44
|
scopeVariablesMapStr: JSON.stringify(options.stateVariables || {}, null, 2),
|
|
45
45
|
pageVariableName: (0, utils_1.getPageVarName)(),
|
|
@@ -97,7 +97,11 @@ const skillActionGenerator = (page, options) => {
|
|
|
97
97
|
properties: {
|
|
98
98
|
reason: {
|
|
99
99
|
type: "string",
|
|
100
|
-
description: "
|
|
100
|
+
description: "Explain how this action will help to complete the task. The reason should align with the task provided",
|
|
101
|
+
},
|
|
102
|
+
action: {
|
|
103
|
+
type: "string",
|
|
104
|
+
description: "Explain the action for which this skill needs to be used. Mention all details about the action so that it could be used by the skill",
|
|
101
105
|
},
|
|
102
106
|
skill: {
|
|
103
107
|
type: "string",
|
|
@@ -107,7 +111,7 @@ const skillActionGenerator = (page, options) => {
|
|
|
107
111
|
.join(", ")}`,
|
|
108
112
|
},
|
|
109
113
|
},
|
|
110
|
-
required: ["reason", "skill"],
|
|
114
|
+
required: ["reason", "action", "skill"],
|
|
111
115
|
},
|
|
112
116
|
},
|
|
113
117
|
},
|
|
@@ -79,12 +79,12 @@ async function prepareFileForUpdateScenario(genConfig, trace) {
|
|
|
79
79
|
});
|
|
80
80
|
await fs_extra_1.default.writeFile(createTestFilePath, (0, web_1.addNewImport)(await fs_extra_1.default.readFile(createTestFilePath, "utf-8"), ["createTest"], "@empiricalrun/test-gen"));
|
|
81
81
|
updateFileSpan?.end();
|
|
82
|
-
const {
|
|
82
|
+
const { pomPrompt, nonSpecFilePrompt } = await (0, context_1.contextForGeneration)(createTestFilePath);
|
|
83
83
|
await (0, fix_ts_errors_1.validateAndFixTypescriptErrors)({
|
|
84
84
|
trace,
|
|
85
85
|
file: createTestFilePath,
|
|
86
|
-
testCode: codePrompt,
|
|
87
86
|
pomCode: pomPrompt,
|
|
87
|
+
nonSpecFileCode: nonSpecFilePrompt,
|
|
88
88
|
testCase: testCase,
|
|
89
89
|
options: genConfig.options,
|
|
90
90
|
});
|
|
@@ -196,7 +196,7 @@ async function injectPwLocatorGenerator(page) {
|
|
|
196
196
|
});
|
|
197
197
|
}
|
|
198
198
|
catch (e) {
|
|
199
|
-
console.warn("Error injecting script in iframe
|
|
199
|
+
console.warn("Error injecting script in iframe.");
|
|
200
200
|
}
|
|
201
201
|
};
|
|
202
202
|
const iframes = document.getElementsByTagName("iframe");
|
|
@@ -235,7 +235,7 @@ async function injectPwLocatorGenerator(page) {
|
|
|
235
235
|
});
|
|
236
236
|
}
|
|
237
237
|
catch (e) {
|
|
238
|
-
console.warn("Error injecting script in iframe:"
|
|
238
|
+
console.warn("Error injecting script in iframe:");
|
|
239
239
|
}
|
|
240
240
|
};
|
|
241
241
|
const iframes = document.getElementsByTagName("iframe");
|
|
@@ -254,7 +254,7 @@ async function injectPwLocatorGenerator(page) {
|
|
|
254
254
|
});
|
|
255
255
|
}
|
|
256
256
|
catch (e) {
|
|
257
|
-
console.warn("Error injecting script in iframe:"
|
|
257
|
+
console.warn("Error injecting script in iframe:");
|
|
258
258
|
}
|
|
259
259
|
}
|
|
260
260
|
exports.injectPwLocatorGenerator = injectPwLocatorGenerator;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { TraceClient } from "@empiricalrun/llm";
|
|
2
2
|
import { CustomLogger } from "../../bin/logger";
|
|
3
3
|
import { TestCase, TestGenConfigOptions } from "../../types";
|
|
4
|
-
export declare function validateAndFixTypescriptErrors({ trace, logger, file,
|
|
4
|
+
export declare function validateAndFixTypescriptErrors({ trace, logger, file, pomCode, nonSpecFileCode, testCase, options, }: {
|
|
5
5
|
trace?: TraceClient;
|
|
6
6
|
logger?: CustomLogger;
|
|
7
7
|
file: string;
|
|
8
|
-
testCode: string;
|
|
9
8
|
pomCode: string;
|
|
9
|
+
nonSpecFileCode: string;
|
|
10
10
|
testCase: TestCase;
|
|
11
11
|
options?: TestGenConfigOptions;
|
|
12
12
|
}): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fix-ts-errors.d.ts","sourceRoot":"","sources":["../../../src/agent/codegen/fix-ts-errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAQhD,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAE7D,wBAAsB,8BAA8B,CAAC,EACnD,KAAK,EACL,MAA2B,EAC3B,IAAI,EACJ,
|
|
1
|
+
{"version":3,"file":"fix-ts-errors.d.ts","sourceRoot":"","sources":["../../../src/agent/codegen/fix-ts-errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAQhD,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAE7D,wBAAsB,8BAA8B,CAAC,EACnD,KAAK,EACL,MAA2B,EAC3B,IAAI,EACJ,OAAO,EACP,eAAe,EACf,QAAQ,EACR,OAAO,GACR,EAAE;IACD,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC,iBAwEA"}
|
|
@@ -9,7 +9,7 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
|
9
9
|
const logger_1 = require("../../bin/logger");
|
|
10
10
|
const web_1 = require("../../bin/utils/platform/web");
|
|
11
11
|
const constants_1 = require("../../constants");
|
|
12
|
-
async function validateAndFixTypescriptErrors({ trace, logger = new logger_1.CustomLogger(), file,
|
|
12
|
+
async function validateAndFixTypescriptErrors({ trace, logger = new logger_1.CustomLogger(), file, pomCode, nonSpecFileCode, testCase, options, }) {
|
|
13
13
|
const validateTypesSpan = trace?.span({ name: "detect-type-errors-in-file" });
|
|
14
14
|
logger.log("Validating types...");
|
|
15
15
|
let errors = (0, web_1.validateTypescript)(file);
|
|
@@ -35,13 +35,13 @@ async function validateAndFixTypescriptErrors({ trace, logger = new logger_1.Cus
|
|
|
35
35
|
errors.forEach((e) => console.warn(e));
|
|
36
36
|
const promptSpan = trace?.span({ name: "fix-type-errors-prompt" });
|
|
37
37
|
const instruction = await (0, llm_1.getPrompt)("fix-file-errors-ts", {
|
|
38
|
-
testFiles: testCode || "",
|
|
39
38
|
pageFiles: pomCode || "",
|
|
39
|
+
fixtureFiles: nonSpecFileCode || "",
|
|
40
40
|
scenarioFile: file,
|
|
41
41
|
errors: errors,
|
|
42
42
|
fileContent: fileContent,
|
|
43
|
-
|
|
44
|
-
});
|
|
43
|
+
scenarioName: testCase.name,
|
|
44
|
+
}, 10);
|
|
45
45
|
promptSpan?.end({ output: { instruction } });
|
|
46
46
|
const llm = new llm_1.LLM({
|
|
47
47
|
trace,
|
|
@@ -48,7 +48,7 @@ async function generateTest(testCase, file, options, trace) {
|
|
|
48
48
|
fs_extra_1.default.createFileSync(file);
|
|
49
49
|
}
|
|
50
50
|
const context = await (0, context_1.contextForGeneration)(file);
|
|
51
|
-
const { codePrompt, pomPrompt, testFileContent } = context;
|
|
51
|
+
const { codePrompt, pomPrompt, nonSpecFilePrompt, testFileContent } = context;
|
|
52
52
|
const { testBlock } = (0, web_1.getTypescriptTestBlock)({
|
|
53
53
|
scenarioName: testCase?.name,
|
|
54
54
|
content: testFileContent,
|
|
@@ -96,8 +96,8 @@ async function generateTest(testCase, file, options, trace) {
|
|
|
96
96
|
trace,
|
|
97
97
|
logger,
|
|
98
98
|
file,
|
|
99
|
-
testCode: codePrompt,
|
|
100
99
|
pomCode: pomPrompt,
|
|
100
|
+
nonSpecFileCode: nonSpecFilePrompt,
|
|
101
101
|
testCase: testCase,
|
|
102
102
|
options,
|
|
103
103
|
});
|
|
@@ -11,7 +11,12 @@ export declare function getUpdateTestCodeCompletion({ testCase, testFileContent,
|
|
|
11
11
|
testFileContent: string;
|
|
12
12
|
trace?: TraceClient;
|
|
13
13
|
options?: TestGenConfigOptions;
|
|
14
|
-
}): Promise<
|
|
14
|
+
}): Promise<{
|
|
15
|
+
filePath: string | undefined;
|
|
16
|
+
oldCode: string | undefined;
|
|
17
|
+
newCode: string | undefined;
|
|
18
|
+
reason: string | undefined;
|
|
19
|
+
}[]>;
|
|
15
20
|
export declare function updateTest(testCase: TestCase, file: string, options: TestGenConfigOptions | undefined, logging?: boolean, validate?: boolean, trace?: TraceClient): Promise<UpdatedTestCase[]>;
|
|
16
21
|
export declare function getAppendCreateTestBlockCompletion({ testFiles, pageFiles, testCase, testFilePath, options, trace, }: {
|
|
17
22
|
trace?: TraceClient;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-flow.d.ts","sourceRoot":"","sources":["../../../src/agent/codegen/update-flow.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,WAAW,EACZ,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"update-flow.d.ts","sourceRoot":"","sources":["../../../src/agent/codegen/update-flow.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAoB3B,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAI7D,KAAK,eAAe,GAAG,QAAQ,GAAG;IAChC,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AAqIF,wBAAsB,2BAA2B,CAAC,EAChD,QAAQ,EACR,eAAe,EACf,SAAS,EACT,SAAS,EACT,YAAY,EACZ,KAAK,EACL,OAAO,GACR,EAAE;IACD,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC,GAAG,OAAO,CACT;IACE,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B,EAAE,CACJ,CA+CA;AAED,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,GAAG,SAAS,EACzC,OAAO,GAAE,OAAc,EACvB,QAAQ,GAAE,OAAc,EACxB,KAAK,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC,eAAe,EAAE,CAAC,CA4D5B;AAED,wBAAsB,kCAAkC,CAAC,EACvD,SAAS,EACT,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,OAAO,EACP,KAAK,GACN,EAAE;IACD,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;CACtB,mBA4DA;AAED,wBAAsB,qBAAqB,CAAC,EAC1C,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,KAAK,EACL,aAAoB,GACrB,EAAE;IACD,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAyC7B"}
|
|
@@ -16,7 +16,7 @@ const constants_1 = require("../../constants");
|
|
|
16
16
|
const session_1 = require("../../session");
|
|
17
17
|
const fix_ts_errors_1 = require("./fix-ts-errors");
|
|
18
18
|
const utils_1 = require("./utils");
|
|
19
|
-
async function applyFileChanges({ validateTypes = true, trace, testCase, fileChanges, logger, testGenOptions, pomPrompt,
|
|
19
|
+
async function applyFileChanges({ validateTypes = true, trace, testCase, fileChanges, logger, testGenOptions, pomPrompt, nonSpecFilePrompt, }) {
|
|
20
20
|
await Promise.allSettled(fileChanges.map(async (fileChange) => {
|
|
21
21
|
if (!fileChange.filePath) {
|
|
22
22
|
return;
|
|
@@ -92,8 +92,8 @@ async function applyFileChanges({ validateTypes = true, trace, testCase, fileCha
|
|
|
92
92
|
trace,
|
|
93
93
|
logger,
|
|
94
94
|
file: fileChange.filePath,
|
|
95
|
-
testCode: codePrompt,
|
|
96
95
|
pomCode: pomPrompt,
|
|
96
|
+
nonSpecFileCode: nonSpecFilePrompt,
|
|
97
97
|
testCase: testCase,
|
|
98
98
|
options: testGenOptions,
|
|
99
99
|
});
|
|
@@ -128,28 +128,30 @@ async function getUpdateTestCodeCompletion({ testCase, testFileContent, testFile
|
|
|
128
128
|
scenarioFile: testFilePath,
|
|
129
129
|
currentScenarioCodeBlock,
|
|
130
130
|
});
|
|
131
|
-
promptSpan?.end({ output: { instruction } });
|
|
132
131
|
const llm = new llm_1.LLM({
|
|
133
132
|
trace,
|
|
134
|
-
provider:
|
|
135
|
-
defaultModel:
|
|
136
|
-
providerApiKey: constants_1.MODEL_API_KEYS[
|
|
133
|
+
provider: "anthropic",
|
|
134
|
+
defaultModel: "claude-3-5-sonnet-latest",
|
|
135
|
+
providerApiKey: constants_1.MODEL_API_KEYS["anthropic"],
|
|
137
136
|
});
|
|
138
137
|
const firstShotMessage = await llm.createChatCompletion({
|
|
139
138
|
messages: instruction,
|
|
140
139
|
modelParameters: {
|
|
141
140
|
...constants_1.DEFAULT_MODEL_PARAMETERS,
|
|
142
141
|
...options?.modelParameters,
|
|
142
|
+
temperature: 0,
|
|
143
143
|
},
|
|
144
144
|
});
|
|
145
145
|
let response = firstShotMessage?.content || "";
|
|
146
|
-
|
|
146
|
+
const fileChanges = (0, utils_1.extractTestUpdates)(response);
|
|
147
|
+
promptSpan?.end({ output: fileChanges });
|
|
148
|
+
return fileChanges;
|
|
147
149
|
}
|
|
148
150
|
exports.getUpdateTestCodeCompletion = getUpdateTestCodeCompletion;
|
|
149
151
|
async function updateTest(testCase, file, options, logging = true, validate = true, trace) {
|
|
150
152
|
const logger = new logger_1.CustomLogger({ useReporter: logging });
|
|
151
153
|
const context = await (0, context_1.contextForGeneration)(file);
|
|
152
|
-
const { codePrompt, pomPrompt, testFileContent } = context;
|
|
154
|
+
const { codePrompt, pomPrompt, nonSpecFilePrompt, testFileContent } = context;
|
|
153
155
|
const generatedTestCases = [];
|
|
154
156
|
logger.logEmptyLine();
|
|
155
157
|
const session = (0, session_1.getSessionDetails)();
|
|
@@ -176,12 +178,11 @@ async function updateTest(testCase, file, options, logging = true, validate = tr
|
|
|
176
178
|
name: "update-test",
|
|
177
179
|
input: request,
|
|
178
180
|
});
|
|
179
|
-
const
|
|
181
|
+
const fileChanges = await getUpdateTestCodeCompletion({
|
|
180
182
|
...request,
|
|
181
183
|
trace: updateTestSpan,
|
|
182
184
|
});
|
|
183
185
|
logger.success("Test generated successfully!");
|
|
184
|
-
const fileChanges = (0, utils_1.extractTestUpdates)(response);
|
|
185
186
|
await applyFileChanges({
|
|
186
187
|
validateTypes: validate,
|
|
187
188
|
trace: updateTestSpan,
|
|
@@ -190,7 +191,7 @@ async function updateTest(testCase, file, options, logging = true, validate = tr
|
|
|
190
191
|
logger,
|
|
191
192
|
testGenOptions: options,
|
|
192
193
|
pomPrompt: pomPrompt,
|
|
193
|
-
|
|
194
|
+
nonSpecFilePrompt: nonSpecFilePrompt,
|
|
194
195
|
});
|
|
195
196
|
if (trace) {
|
|
196
197
|
logger.log(`Trace: ${trace?.getTraceUrl()}`);
|
|
@@ -199,7 +200,7 @@ async function updateTest(testCase, file, options, logging = true, validate = tr
|
|
|
199
200
|
...testCase,
|
|
200
201
|
updatedFiles: fileChanges.map((f) => f.filePath),
|
|
201
202
|
});
|
|
202
|
-
updateTestSpan?.end({ output: {
|
|
203
|
+
updateTestSpan?.end({ output: { fileChanges } });
|
|
203
204
|
await (0, llm_1.flushAllTraces)();
|
|
204
205
|
return generatedTestCases;
|
|
205
206
|
}
|
|
@@ -273,7 +274,7 @@ async function appendCreateTestBlock({ testCase, file, options, trace, validateT
|
|
|
273
274
|
content: scenarioFileContent,
|
|
274
275
|
},
|
|
275
276
|
]);
|
|
276
|
-
const {
|
|
277
|
+
const { pomPrompt, nonSpecFilePrompt } = context;
|
|
277
278
|
const generatedTestCases = [];
|
|
278
279
|
const appendCreateTestResp = await getAppendCreateTestBlockCompletion({
|
|
279
280
|
testCase,
|
|
@@ -291,7 +292,7 @@ async function appendCreateTestBlock({ testCase, file, options, trace, validateT
|
|
|
291
292
|
logger,
|
|
292
293
|
testGenOptions: options,
|
|
293
294
|
pomPrompt: pomPrompt,
|
|
294
|
-
|
|
295
|
+
nonSpecFilePrompt: nonSpecFilePrompt,
|
|
295
296
|
validateTypes,
|
|
296
297
|
});
|
|
297
298
|
if (trace) {
|
|
@@ -16,7 +16,10 @@ export declare function getNextAction({ task, executedActions, failedActions, pa
|
|
|
16
16
|
actions: PlaywrightActions;
|
|
17
17
|
disableSkills: boolean;
|
|
18
18
|
useHints: boolean;
|
|
19
|
-
annotations?:
|
|
19
|
+
annotations?: {
|
|
20
|
+
elementID: string;
|
|
21
|
+
text: string;
|
|
22
|
+
}[];
|
|
20
23
|
}): Promise<import("openai/resources/index.mjs").ChatCompletionMessageToolCall | undefined>;
|
|
21
24
|
export declare function createTestUsingMasterAgent({ task, page, testCase, options, scopeVars, }: {
|
|
22
25
|
task: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/master/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,GAAG,EACH,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAclD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EACL,oBAAoB,EAErB,MAAM,aAAa,CAAC;AAoBrB,wBAAsB,aAAa,CAAC,EAClC,IAAI,EACJ,eAAe,EACf,aAAa,EACb,OAAO,EACP,KAAK,EACL,GAAG,EACH,OAAO,EACP,cAAc,EACd,uBAAuB,EACvB,OAAO,EACP,aAAa,EACb,QAAgB,EAChB,WAAW,GACZ,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,EAAE,GAAG,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,OAAO,EAAE,iBAAiB,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/master/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,GAAG,EACH,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAclD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EACL,oBAAoB,EAErB,MAAM,aAAa,CAAC;AAoBrB,wBAAsB,aAAa,CAAC,EAClC,IAAI,EACJ,eAAe,EACf,aAAa,EACb,OAAO,EACP,KAAK,EACL,GAAG,EACH,OAAO,EACP,cAAc,EACd,uBAAuB,EACvB,OAAO,EACP,aAAa,EACb,QAAgB,EAChB,WAAW,GACZ,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,EAAE,GAAG,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,OAAO,EAAE,iBAAiB,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACrD,2FA6FA;AAGD,wBAAsB,0BAA0B,CAAC,EAC/C,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,SAAS,GACV,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,oBAAoB,CAAC;IAC9B,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;;;GAiUA"}
|
package/dist/agent/master/run.js
CHANGED
|
@@ -52,8 +52,10 @@ async function getNextAction({ task, executedActions, failedActions, pageUrl, tr
|
|
|
52
52
|
failedActions: failedActions.map((a) => a).join("\n"),
|
|
53
53
|
executedActions: executedActions.map((a) => a).join("\n"),
|
|
54
54
|
pageUrl,
|
|
55
|
-
annotations
|
|
56
|
-
|
|
55
|
+
annotations: annotations
|
|
56
|
+
?.map((a) => `${a.elementID}:${a.text}`)
|
|
57
|
+
.join("\n"),
|
|
58
|
+
}, 27);
|
|
57
59
|
// assuming there is only one user message in the prompt. if there is a change in langfuse prompt format, this will need to be updated
|
|
58
60
|
const userMessage = promptMessages.filter((m) => m.role === "user")[0];
|
|
59
61
|
const systemMessage = promptMessages.filter((m) => m.role === "system")[0];
|
|
@@ -175,7 +177,7 @@ async function createTestUsingMasterAgent({ task, page, testCase, options, scope
|
|
|
175
177
|
const plannerResp = await (0, run_time_planner_1.runtimePlanner)({
|
|
176
178
|
trace: masterAgentSpan,
|
|
177
179
|
task,
|
|
178
|
-
conversation: [
|
|
180
|
+
conversation: [...masterAgentActions],
|
|
179
181
|
pages: getPageVariables(actions.getStateVariables()),
|
|
180
182
|
currentPage: (0, utils_1.getPageVarName)(),
|
|
181
183
|
});
|
|
@@ -210,8 +212,18 @@ async function createTestUsingMasterAgent({ task, page, testCase, options, scope
|
|
|
210
212
|
// @ts-ignore
|
|
211
213
|
// eslint-disable-next-line no-undef
|
|
212
214
|
window.annotationInstance = annotateClickableElements();
|
|
215
|
+
const annotations = Object.entries(
|
|
213
216
|
// @ts-ignore
|
|
214
|
-
|
|
217
|
+
window.annotationInstance.annotations).map(([key, value]) => ({
|
|
218
|
+
elementID: key, // Assign the key to elementID
|
|
219
|
+
text:
|
|
220
|
+
//@ts-ignore
|
|
221
|
+
value.node.text?.trim() ||
|
|
222
|
+
//@ts-ignore
|
|
223
|
+
value.node.textContent?.trim() ||
|
|
224
|
+
"<This is an icon or image. Check the screenshot>",
|
|
225
|
+
}));
|
|
226
|
+
return annotations;
|
|
215
227
|
});
|
|
216
228
|
await page.waitForTimeout(2000);
|
|
217
229
|
const annonationBuffer = await page.screenshot({
|
|
@@ -13,7 +13,10 @@ export declare const triggerHintsFlow: ({ outputFromGetNextAction, generatedAnno
|
|
|
13
13
|
action: string;
|
|
14
14
|
elementAnnotation?: string;
|
|
15
15
|
};
|
|
16
|
-
generatedAnnotations:
|
|
16
|
+
generatedAnnotations: {
|
|
17
|
+
elementID: string;
|
|
18
|
+
text: string;
|
|
19
|
+
}[];
|
|
17
20
|
page: TestGenPage;
|
|
18
21
|
llm: LLM;
|
|
19
22
|
trace?: TraceClient | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"with-hints.d.ts","sourceRoot":"","sources":["../../../src/agent/master/with-hints.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,MAAM,MAAM,QAAQ,CAAC;AAI5B,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,eAAO,MAAM,0BAA0B;iBAMxB,OAAO,8BAA8B;;oBAElC,MAAM;6BACG,MAAM;MAC7B,MAAM,GAAG,OAAO,yBAAyB,EAiC5C,CAAC;AAEF,eAAO,MAAM,gBAAgB;6BAOF;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B;0BACqB,
|
|
1
|
+
{"version":3,"file":"with-hints.d.ts","sourceRoot":"","sources":["../../../src/agent/master/with-hints.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,MAAM,MAAM,QAAQ,CAAC;AAI5B,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,eAAO,MAAM,0BAA0B;iBAMxB,OAAO,8BAA8B;;oBAElC,MAAM;6BACG,MAAM;MAC7B,MAAM,GAAG,OAAO,yBAAyB,EAiC5C,CAAC;AAEF,eAAO,MAAM,gBAAgB;6BAOF;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B;0BACqB;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE;UACrD,WAAW;SACZ,GAAG;;MAEN,QAAQ;IACV,sBAAsB,EAAE,OAAO,CAAC;IAChC,wBAAwB,EAAE,OAAO,qBAAqB,GAAG,SAAS,CAAC;CACpE,CAwGA,CAAC"}
|
|
@@ -37,7 +37,7 @@ const triggerHintsFlow = async ({ outputFromGetNextAction, generatedAnnotations,
|
|
|
37
37
|
try {
|
|
38
38
|
const hasElementAnnotation = outputFromGetNextAction?.elementAnnotation?.length &&
|
|
39
39
|
outputFromGetNextAction?.elementAnnotation?.trim()?.length &&
|
|
40
|
-
generatedAnnotations
|
|
40
|
+
generatedAnnotations.some((annotation) => annotation.elementID === outputFromGetNextAction?.elementAnnotation);
|
|
41
41
|
trace?.event({
|
|
42
42
|
name: "has-element-annotation",
|
|
43
43
|
output: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-time-planner.d.ts","sourceRoot":"","sources":["../../../src/agent/planner/run-time-planner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,EACnC,KAAK,EACL,IAAI,EACJ,YAAY,EACZ,KAAK,EACL,WAAW,GACZ,EAAE;IACD,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;;;;
|
|
1
|
+
{"version":3,"file":"run-time-planner.d.ts","sourceRoot":"","sources":["../../../src/agent/planner/run-time-planner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,EACnC,KAAK,EACL,IAAI,EACJ,YAAY,EACZ,KAAK,EACL,WAAW,GACZ,EAAE;IACD,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;;;;GAiHA"}
|
|
@@ -22,14 +22,14 @@ async function runtimePlanner({ trace, task, conversation, pages, currentPage, }
|
|
|
22
22
|
{
|
|
23
23
|
role: "system",
|
|
24
24
|
content: `
|
|
25
|
-
Given a
|
|
26
|
-
These
|
|
25
|
+
Given a successfully executed actions that lists only the actions that were successfully executed and a task comprising multiple actions, your goal is to analyse the list and determine if the entire task is completed.
|
|
26
|
+
These actions are executed by AI agents using Playwright on a browser. These agents already have access to browser tabs to execute actions. The successfully executed actions on browser post browser has opened, is provided to you as successfully executed actions.
|
|
27
27
|
|
|
28
28
|
If the task is not fully completed, identify which specific actions are missing and suggest next steps to complete the task. Assume that the conversation provided is entirely truthful and no additional actions were performed beyond those listed.
|
|
29
29
|
|
|
30
30
|
To fulfil your goal, follow these steps:
|
|
31
31
|
- Divide the task into individual actions.
|
|
32
|
-
- Compare each task action against the actions listed in the
|
|
32
|
+
- Compare each task action against the actions listed in the successfully executed actions list.
|
|
33
33
|
- Identify which actions have been executed and which have not.
|
|
34
34
|
- If all actions are executed, respond with the task as done.
|
|
35
35
|
- If any actions are missing, respond with the task as not done, listing all actions and specifying which are complete and which are missing.
|
|
@@ -41,9 +41,13 @@ To fulfil your goal, follow these steps:
|
|
|
41
41
|
content: `
|
|
42
42
|
Task: ${task}
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
----
|
|
45
|
+
|
|
46
|
+
Following are successfully executed actions:
|
|
45
47
|
${conversation.join("\n")}
|
|
46
48
|
|
|
49
|
+
----
|
|
50
|
+
|
|
47
51
|
Current page:
|
|
48
52
|
${currentPage}
|
|
49
53
|
`,
|
|
@@ -2,6 +2,7 @@ export declare function createGitIgnoreFileFilter(): Promise<(pathname: string)
|
|
|
2
2
|
export declare function contextForGeneration(file?: string): Promise<{
|
|
3
3
|
codePrompt: string | undefined;
|
|
4
4
|
pomPrompt: string | undefined;
|
|
5
|
+
nonSpecFilePrompt: string | undefined;
|
|
5
6
|
testFileContent: string;
|
|
6
7
|
}>;
|
|
7
8
|
export declare function fetchAppKnowledge(): Promise<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/bin/utils/context.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/bin/utils/context.ts"],"names":[],"mappings":"AAQA,wBAAsB,yBAAyB,2CAS9C;AAED,wBAAsB,oBAAoB,CAAC,IAAI,CAAC,EAAE,MAAM;;;;;GAQvD;AAED,wBAAsB,iBAAiB,oBAYtC"}
|
|
@@ -23,6 +23,7 @@ async function contextForGeneration(file) {
|
|
|
23
23
|
return {
|
|
24
24
|
codePrompt: await (0, fs_1.generatePromptFromDirectory)("./tests", filter),
|
|
25
25
|
pomPrompt: await (0, fs_1.generatePromptFromDirectory)("./pages", filter),
|
|
26
|
+
nonSpecFilePrompt: await (0, fs_1.generatePromptFromNonSpecFiles)("./tests", filter),
|
|
26
27
|
testFileContent: file ? await fs_extra_1.default.readFile(file, "utf-8") : "",
|
|
27
28
|
};
|
|
28
29
|
}
|
|
@@ -2,4 +2,5 @@ import { FileContent } from "../../../types";
|
|
|
2
2
|
export declare function readFilesInDirectory(dir: string | undefined, filterFunc: (file: string) => boolean): Promise<FileContent[]>;
|
|
3
3
|
export declare function convertFileContentsToString(files?: FileContent[]): string;
|
|
4
4
|
export declare function generatePromptFromDirectory(dir: string | undefined, filterFunc: (file: string) => boolean): Promise<string | undefined>;
|
|
5
|
+
export declare function generatePromptFromNonSpecFiles(dir: string | undefined, filterFunc: (file: string) => boolean): Promise<string | undefined>;
|
|
5
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/bin/utils/fs/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,wBAAsB,oBAAoB,CACxC,GAAG,oBAAa,EAChB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,0BAgBtC;AAED,wBAAgB,2BAA2B,CAAC,KAAK,GAAE,WAAW,EAAO,UAQpE;AAED,wBAAsB,2BAA2B,CAC/C,GAAG,oBAAK,EACR,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,+BAStC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/bin/utils/fs/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,wBAAsB,oBAAoB,CACxC,GAAG,oBAAa,EAChB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,0BAgBtC;AAED,wBAAgB,2BAA2B,CAAC,KAAK,GAAE,WAAW,EAAO,UAQpE;AAED,wBAAsB,2BAA2B,CAC/C,GAAG,oBAAK,EACR,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,+BAStC;AAED,wBAAsB,8BAA8B,CAClD,GAAG,oBAAa,EAChB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,+BAgBtC"}
|
|
@@ -3,7 +3,7 @@ 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.generatePromptFromDirectory = exports.convertFileContentsToString = exports.readFilesInDirectory = void 0;
|
|
6
|
+
exports.generatePromptFromNonSpecFiles = exports.generatePromptFromDirectory = exports.convertFileContentsToString = exports.readFilesInDirectory = void 0;
|
|
7
7
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
async function readFilesInDirectory(dir = "", filterFunc) {
|
|
@@ -44,3 +44,20 @@ async function generatePromptFromDirectory(dir = "", filterFunc) {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
exports.generatePromptFromDirectory = generatePromptFromDirectory;
|
|
47
|
+
async function generatePromptFromNonSpecFiles(dir = "", filterFunc) {
|
|
48
|
+
try {
|
|
49
|
+
let nonSpecFiles = [];
|
|
50
|
+
const files = await readFilesInDirectory(dir, filterFunc);
|
|
51
|
+
for (const file of files) {
|
|
52
|
+
if (!file.filePath.endsWith(".spec.ts")) {
|
|
53
|
+
nonSpecFiles.push(file);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const prompt = convertFileContentsToString(nonSpecFiles);
|
|
57
|
+
return prompt;
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
console.error("Error reading directory:", error);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.generatePromptFromNonSpecFiles = generatePromptFromNonSpecFiles;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/bin/utils/platform/web/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAGL,IAAI,EAEJ,UAAU,EAEX,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,eAAO,MAAM,gCAAgC,eAC/B,UAAU,KACrB,MAgBF,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,YAAY,EACZ,MAAM,EACN,OAAO,GACR,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG;IACF,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,QAAQ,EAAE,IAAI,GAAG,SAAS,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;CACnB,CA2CA;AAwBD,wBAAsB,0CAA0C,CAC9D,QAAQ,EAAE,MAAM,oBA+BjB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,IAAI,GAAG,SAAS,GACrB,IAAI,GAAG,SAAS,CA4BlB;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAG5E;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CA8C7D;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,mCAWjB;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,iBAShD;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,iBAQhD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,UAE5E;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,iBAMpD;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,UAcpD;AAED,wBAAsB,iCAAiC,CAAC,QAAQ,EAAE,MAAM,+BAoBvE;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,UA0CtB;AAED,eAAO,MAAM,6BAA6B;qBAKvB,MAAM;iBACV,MAAM;YACX,MAAM,EAAE;YA2DjB,CAAC;AAEF,eAAO,MAAM,iCAAiC,cACjC,MAAM,EAAE,gBACL,MAAM,sBAyBrB,CAAC;AAEF,wBAAsB,qBAAqB,CAAC,EAC1C,YAAY,EACZ,QAAQ,EACR,MAAM,GACP,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/bin/utils/platform/web/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAGL,IAAI,EAEJ,UAAU,EAEX,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,eAAO,MAAM,gCAAgC,eAC/B,UAAU,KACrB,MAgBF,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,YAAY,EACZ,MAAM,EACN,OAAO,GACR,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG;IACF,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,QAAQ,EAAE,IAAI,GAAG,SAAS,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;CACnB,CA2CA;AAwBD,wBAAsB,0CAA0C,CAC9D,QAAQ,EAAE,MAAM,oBA+BjB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,IAAI,GAAG,SAAS,GACrB,IAAI,GAAG,SAAS,CA4BlB;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAG5E;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CA8C7D;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,mCAWjB;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,iBAShD;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,iBAQhD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,UAE5E;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,iBAMpD;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,UAcpD;AAED,wBAAsB,iCAAiC,CAAC,QAAQ,EAAE,MAAM,+BAoBvE;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,UA0CtB;AAED,eAAO,MAAM,6BAA6B;qBAKvB,MAAM;iBACV,MAAM;YACX,MAAM,EAAE;YA2DjB,CAAC;AAEF,eAAO,MAAM,iCAAiC,cACjC,MAAM,EAAE,gBACL,MAAM,sBAyBrB,CAAC;AAEF,wBAAsB,qBAAqB,CAAC,EAC1C,YAAY,EACZ,QAAQ,EACR,MAAM,GACP,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,iBA8CA;AAED,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EAAE,iBA2BzB;AAED,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;CACpB,WAYA;AAED,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,MAAM,GACP,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,UAOA;AAED,wBAAgB,+BAA+B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CA4B5E"}
|
|
@@ -404,29 +404,25 @@ async function addUserContextFixture({ scenarioName, filePath, suites, }) {
|
|
|
404
404
|
return;
|
|
405
405
|
}
|
|
406
406
|
const fileContent = await fs_extra_1.default.readFile(filePath, "utf-8");
|
|
407
|
-
const { testNode
|
|
407
|
+
const { testNode } = getTypescriptTestBlock({
|
|
408
408
|
scenarioName,
|
|
409
409
|
content: fileContent,
|
|
410
410
|
suites,
|
|
411
411
|
});
|
|
412
412
|
const currentBlock = testNode?.getText();
|
|
413
|
-
const
|
|
414
|
-
if (
|
|
415
|
-
const
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
const
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
const
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
.replace("}", ", userContext }");
|
|
427
|
-
destructuringParam.replaceWithText(updatedImport);
|
|
428
|
-
await fs_extra_1.default.writeFile(filePath, fileContent.replace(currentBlock, testNode.getText()), "utf-8");
|
|
429
|
-
}
|
|
413
|
+
const arrowFunction = testNode?.getFirstDescendantByKind(ts_morph_1.SyntaxKind.ArrowFunction);
|
|
414
|
+
if (arrowFunction) {
|
|
415
|
+
const param = arrowFunction.getParameters()[0]; // Get the first parameter
|
|
416
|
+
const destructuringParam = param?.getFirstDescendantByKind(ts_morph_1.SyntaxKind.ObjectBindingPattern);
|
|
417
|
+
if (destructuringParam) {
|
|
418
|
+
const elements = destructuringParam.getElements();
|
|
419
|
+
const userContextExists = elements.some((e) => e.getText().includes("userContext"));
|
|
420
|
+
if (!userContextExists) {
|
|
421
|
+
const updatedImport = destructuringParam
|
|
422
|
+
.getText()
|
|
423
|
+
.replace("}", ", userContext }");
|
|
424
|
+
destructuringParam.replaceWithText(updatedImport);
|
|
425
|
+
await fs_extra_1.default.writeFile(filePath, fileContent.replace(currentBlock, testNode.getText()), "utf-8");
|
|
430
426
|
}
|
|
431
427
|
}
|
|
432
428
|
}
|
|
@@ -103,8 +103,8 @@ function annotateClickableElements(options = {}) {
|
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
// Check if an element is clickable
|
|
106
|
-
function isElementClickable(element) {
|
|
107
|
-
|
|
106
|
+
function isElementClickable(element, windowToAnnotate) {
|
|
107
|
+
if (!(element instanceof windowToAnnotate.Element)) return false;
|
|
108
108
|
|
|
109
109
|
const tagName = element.tagName.toLowerCase();
|
|
110
110
|
let isClickable = false;
|
|
@@ -380,7 +380,7 @@ function annotateClickableElements(options = {}) {
|
|
|
380
380
|
|
|
381
381
|
// Filter for clickable elements
|
|
382
382
|
const clickableElements = Array.from(windowToAnnotate.document.querySelectorAll("*")).filter((el) => {
|
|
383
|
-
const isClickable = isElementClickable(el);
|
|
383
|
+
const isClickable = isElementClickable(el, windowToAnnotate);
|
|
384
384
|
const isClickNotBlocked = isElementClickNotBlocked(el, windowToAnnotate);
|
|
385
385
|
return isClickable && isClickNotBlocked;
|
|
386
386
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-scenario-agent.evals.d.ts","sourceRoot":"","sources":["../../src/evals/update-scenario-agent.evals.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"update-scenario-agent.evals.d.ts","sourceRoot":"","sources":["../../src/evals/update-scenario-agent.evals.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAUpC,QAAA,MAAM,+BAA+B,EAAE,UAqDtC,CAAC;AAEF,eAAe,+BAA+B,CAAC"}
|
|
@@ -5,10 +5,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const js_levenshtein_1 = __importDefault(require("js-levenshtein"));
|
|
7
7
|
const update_flow_1 = require("../agent/codegen/update-flow");
|
|
8
|
-
const utils_1 = require("../agent/codegen/utils");
|
|
9
8
|
const updateScenarioCodeAgentEvaluate = async ({ item, trace }) => {
|
|
10
9
|
const { testCase, testFiles, pageFiles, testFilePath, testFileContent } = item.input;
|
|
11
|
-
const
|
|
10
|
+
const fileChanges = await (0, update_flow_1.getUpdateTestCodeCompletion)({
|
|
12
11
|
testCase,
|
|
13
12
|
testFiles,
|
|
14
13
|
pageFiles,
|
|
@@ -16,8 +15,7 @@ const updateScenarioCodeAgentEvaluate = async ({ item, trace }) => {
|
|
|
16
15
|
testFileContent,
|
|
17
16
|
trace,
|
|
18
17
|
});
|
|
19
|
-
const
|
|
20
|
-
const expectedFileChanges = (0, utils_1.extractTestUpdates)(item.expectedOutput);
|
|
18
|
+
const expectedFileChanges = item.expectedOutput;
|
|
21
19
|
const fileChangeCount = fileChanges.length;
|
|
22
20
|
const expectedFileChangeCount = expectedFileChanges.length;
|
|
23
21
|
const correctFilePathChanges = expectedFileChanges.every((ef) => fileChanges.some((f) => f.filePath === ef.filePath));
|
|
@@ -43,7 +41,7 @@ const updateScenarioCodeAgentEvaluate = async ({ item, trace }) => {
|
|
|
43
41
|
value: score,
|
|
44
42
|
},
|
|
45
43
|
],
|
|
46
|
-
output:
|
|
44
|
+
output: fileChanges,
|
|
47
45
|
};
|
|
48
46
|
};
|
|
49
47
|
exports.default = updateScenarioCodeAgentEvaluate;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@empiricalrun/test-gen",
|
|
3
|
-
"version": "0.38.
|
|
3
|
+
"version": "0.38.15",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"registry": "https://registry.npmjs.org/",
|
|
6
6
|
"access": "public"
|
|
@@ -55,10 +55,10 @@
|
|
|
55
55
|
"remove-markdown": "^0.5.5",
|
|
56
56
|
"sanitize-html": "^2.13.0",
|
|
57
57
|
"slugify": "^1.6.6",
|
|
58
|
-
"ts-morph": "^
|
|
58
|
+
"ts-morph": "^24.0.0",
|
|
59
59
|
"tsx": "^4.16.2",
|
|
60
60
|
"typescript": "^5.3.3",
|
|
61
|
-
"@empiricalrun/llm": "^0.9.
|
|
61
|
+
"@empiricalrun/llm": "^0.9.26",
|
|
62
62
|
"@empiricalrun/r2-uploader": "^0.3.6",
|
|
63
63
|
"@empiricalrun/reporter": "^0.21.3"
|
|
64
64
|
},
|