@empiricalrun/test-gen 0.27.9 → 0.27.10
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 +10 -0
- package/dist/actions/fill.d.ts.map +1 -1
- package/dist/actions/fill.js +18 -3
- package/dist/actions/index.d.ts +3 -1
- package/dist/actions/index.d.ts.map +1 -1
- package/dist/actions/index.js +20 -10
- package/dist/actions/text-content.d.ts +4 -0
- package/dist/actions/text-content.d.ts.map +1 -0
- package/dist/actions/text-content.js +53 -0
- package/dist/agent/browsing/index.d.ts.map +1 -1
- package/dist/agent/browsing/index.js +2 -0
- package/dist/agent/browsing/utils.d.ts.map +1 -1
- package/dist/agent/browsing/utils.js +17 -51
- package/dist/agent/codegen/create-test-block.d.ts +9 -0
- package/dist/agent/codegen/create-test-block.d.ts.map +1 -0
- package/dist/agent/codegen/create-test-block.js +60 -0
- package/dist/agent/codegen/update-flow.d.ts +8 -0
- package/dist/agent/codegen/update-flow.d.ts.map +1 -1
- package/dist/agent/codegen/update-flow.js +134 -56
- package/dist/reporter/index.d.ts +1 -0
- package/dist/reporter/index.d.ts.map +1 -1
- package/dist/types/index.d.ts +3 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @empiricalrun/test-gen
|
|
2
2
|
|
|
3
|
+
## 0.27.10
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 66aa7b6: fix: master agent gives up on blank page and coding agent hallucination
|
|
8
|
+
- Updated dependencies [aadad32]
|
|
9
|
+
- Updated dependencies [bac164e]
|
|
10
|
+
- @empiricalrun/reporter@0.18.1
|
|
11
|
+
- @empiricalrun/r2-uploader@0.3.0
|
|
12
|
+
|
|
3
13
|
## 0.27.9
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fill.d.ts","sourceRoot":"","sources":["../../src/actions/fill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAIrD,eAAO,MAAM,2BAA2B,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"fill.d.ts","sourceRoot":"","sources":["../../src/actions/fill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAIrD,eAAO,MAAM,2BAA2B,uBAAuB,CAAC;AAGhE,eAAO,MAAM,mBAAmB,EAAE,yBAgEjC,CAAC"}
|
package/dist/actions/fill.js
CHANGED
|
@@ -4,12 +4,16 @@ exports.fillActionGenerator = exports.PLAYWRIGHT_FILL_ACTION_NAME = void 0;
|
|
|
4
4
|
const constants_1 = require("./constants");
|
|
5
5
|
const utils_1 = require("./utils");
|
|
6
6
|
exports.PLAYWRIGHT_FILL_ACTION_NAME = "fill_input_element";
|
|
7
|
-
const
|
|
7
|
+
const NO_STATE_VARIABLE = "NA";
|
|
8
|
+
const fillActionGenerator = (page, options) => {
|
|
9
|
+
const stateVariableNames = Object.keys(options?.stateVariables || {});
|
|
10
|
+
stateVariableNames.push(NO_STATE_VARIABLE);
|
|
8
11
|
return {
|
|
9
12
|
execute: async (args) => {
|
|
10
13
|
const css = args.css_selector;
|
|
11
14
|
const locator = await (0, utils_1.getPlaywrightLocatorUsingCssSelector)(css, page);
|
|
12
|
-
const
|
|
15
|
+
const textToFill = options?.stateVariables[args.variable_name] || args.text;
|
|
16
|
+
const exec = new Function("page", `return page.${locator}.fill("${textToFill}", { timeout: 3000 })`);
|
|
13
17
|
await exec(page);
|
|
14
18
|
return {
|
|
15
19
|
locator,
|
|
@@ -32,6 +36,17 @@ const fillActionGenerator = (page) => {
|
|
|
32
36
|
type: "string",
|
|
33
37
|
description: "The text to fill the input element with",
|
|
34
38
|
},
|
|
39
|
+
variable_name: {
|
|
40
|
+
type: "string",
|
|
41
|
+
enum: stateVariableNames,
|
|
42
|
+
description: `variable name whose value needs to be filled in the input element.
|
|
43
|
+
The variable name and values are:
|
|
44
|
+
|
|
45
|
+
${JSON.stringify(stateVariableNames, null, 2)}
|
|
46
|
+
|
|
47
|
+
- Choose the variable name based on the value above.
|
|
48
|
+
- Set variable_name as 'NA' if there is no variable to be used.`,
|
|
49
|
+
},
|
|
35
50
|
css_selector: {
|
|
36
51
|
type: "string",
|
|
37
52
|
description: "CSS selector to identify the element uniquely.When creating CSS selectors, ensure they are unique to the page and specific enough to select only one element.",
|
|
@@ -41,7 +56,7 @@ const fillActionGenerator = (page) => {
|
|
|
41
56
|
description: constants_1.DEFAULT_ACTION_REASON_PROMPT,
|
|
42
57
|
},
|
|
43
58
|
},
|
|
44
|
-
required: ["text", "css_selector", "reason"],
|
|
59
|
+
required: ["variable_name", "text", "css_selector", "reason"],
|
|
45
60
|
},
|
|
46
61
|
},
|
|
47
62
|
},
|
package/dist/actions/index.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { Page } from "playwright";
|
|
2
2
|
import { ActionSchema } from "../types";
|
|
3
3
|
export declare class PlaywrightActions {
|
|
4
|
-
private
|
|
4
|
+
private page;
|
|
5
|
+
private actionGenerators;
|
|
5
6
|
private recordedActions;
|
|
7
|
+
private stateVariables;
|
|
6
8
|
constructor(page: Page);
|
|
7
9
|
executeAction(name: string | undefined, args: Record<string, any>): Promise<void>;
|
|
8
10
|
getActionSchemas(): ActionSchema[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/actions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAIlC,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/actions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAIlC,OAAO,EAAE,YAAY,EAA6B,MAAM,UAAU,CAAC;AASnE,qBAAa,iBAAiB;IAMhB,OAAO,CAAC,IAAI;IAJxB,OAAO,CAAC,gBAAgB,CAA8B;IACtD,OAAO,CAAC,eAAe,CAAmC;IAC1D,OAAO,CAAC,cAAc,CAA2B;gBAE7B,IAAI,EAAE,IAAI;IAaxB,aAAa,CAAC,IAAI,oBAAa,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAyBhE,gBAAgB,IAAI,YAAY,EAAE;IAMlC,YAAY;IAIZ,gBAAgB,CAAC,KAAK,EAAE,MAAM;IAO9B,UAAU;CAUX"}
|
package/dist/actions/index.js
CHANGED
|
@@ -9,22 +9,30 @@ const done_1 = require("./done");
|
|
|
9
9
|
const fill_1 = require("./fill");
|
|
10
10
|
const goto_1 = require("./goto");
|
|
11
11
|
const reload_page_1 = require("./reload-page");
|
|
12
|
+
const text_content_1 = require("./text-content");
|
|
12
13
|
class PlaywrightActions {
|
|
13
|
-
|
|
14
|
+
page;
|
|
15
|
+
// private actions: Action[];
|
|
16
|
+
actionGenerators;
|
|
14
17
|
recordedActions;
|
|
18
|
+
stateVariables = {};
|
|
15
19
|
constructor(page) {
|
|
16
|
-
this.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
this.page = page;
|
|
21
|
+
this.actionGenerators = [
|
|
22
|
+
fill_1.fillActionGenerator,
|
|
23
|
+
goto_1.gotoActionGenerator,
|
|
24
|
+
click_1.clickActionGenerator,
|
|
25
|
+
done_1.doneActionGenerator,
|
|
26
|
+
assert_1.assertTextVisibilityActionGenerator,
|
|
27
|
+
reload_page_1.reloadActionGenerator,
|
|
28
|
+
text_content_1.textContentActionGenerator,
|
|
23
29
|
];
|
|
24
30
|
this.recordedActions = [];
|
|
25
31
|
}
|
|
26
32
|
async executeAction(name = "", args) {
|
|
27
|
-
const [action] = this.
|
|
33
|
+
const [action] = this.actionGenerators
|
|
34
|
+
.map((a) => a(this.page, { stateVariables: this.stateVariables }))
|
|
35
|
+
.filter((a) => a.name === name);
|
|
28
36
|
if (!action) {
|
|
29
37
|
throw Error(`No action registered for action: ${name}`);
|
|
30
38
|
}
|
|
@@ -47,7 +55,9 @@ class PlaywrightActions {
|
|
|
47
55
|
}
|
|
48
56
|
}
|
|
49
57
|
getActionSchemas() {
|
|
50
|
-
return this.
|
|
58
|
+
return this.actionGenerators
|
|
59
|
+
.map((a) => a(this.page, { stateVariables: this.stateVariables }))
|
|
60
|
+
.map((a) => a.schema);
|
|
51
61
|
}
|
|
52
62
|
generateCode() {
|
|
53
63
|
return this.recordedActions.map((a) => a.code).join("\n");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-content.d.ts","sourceRoot":"","sources":["../../src/actions/text-content.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAIrD,eAAO,MAAM,2BAA2B,iBAAiB,CAAC;AAE1D,eAAO,MAAM,0BAA0B,EAAE,yBAkDxC,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.textContentActionGenerator = exports.PLAYWRIGHT_GOTO_ACTION_NAME = void 0;
|
|
4
|
+
const constants_1 = require("./constants");
|
|
5
|
+
const utils_1 = require("./utils");
|
|
6
|
+
exports.PLAYWRIGHT_GOTO_ACTION_NAME = "text_content";
|
|
7
|
+
const textContentActionGenerator = (page, options) => {
|
|
8
|
+
return {
|
|
9
|
+
execute: async (args) => {
|
|
10
|
+
const css = args.css_selector;
|
|
11
|
+
const locator = await (0, utils_1.getPlaywrightLocatorUsingCssSelector)(css, page);
|
|
12
|
+
const exec = new Function("page", `return page.${locator}.textContent()`);
|
|
13
|
+
const value = (await exec(page));
|
|
14
|
+
if (options) {
|
|
15
|
+
options.stateVariables[args.variable_name] = value;
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
locator,
|
|
19
|
+
};
|
|
20
|
+
},
|
|
21
|
+
template: (args, options) => {
|
|
22
|
+
const templ = `const ${args.variable_name} = await ${(0, utils_1.getPageVarName)()}.${options.locator}.textContent();`;
|
|
23
|
+
return templ;
|
|
24
|
+
},
|
|
25
|
+
name: exports.PLAYWRIGHT_GOTO_ACTION_NAME,
|
|
26
|
+
schema: {
|
|
27
|
+
type: "function",
|
|
28
|
+
function: {
|
|
29
|
+
name: exports.PLAYWRIGHT_GOTO_ACTION_NAME,
|
|
30
|
+
description: "extract text content of the element",
|
|
31
|
+
parameters: {
|
|
32
|
+
type: "object",
|
|
33
|
+
properties: {
|
|
34
|
+
variable_name: {
|
|
35
|
+
type: "string",
|
|
36
|
+
description: "name of the variable to store the text content. The variable name should describe what the text content is about.",
|
|
37
|
+
},
|
|
38
|
+
css_selector: {
|
|
39
|
+
type: "string",
|
|
40
|
+
description: "CSS selector to identify the element uniquely.When creating CSS selectors, ensure they are unique to the page and specific enough to select only one element.",
|
|
41
|
+
},
|
|
42
|
+
reason: {
|
|
43
|
+
type: "string",
|
|
44
|
+
description: constants_1.DEFAULT_ACTION_REASON_PROMPT,
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
required: ["variable_name", "css_selector", "reason"],
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
exports.textContentActionGenerator = textContentActionGenerator;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAYlC,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAMnD,KAAK,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,GAAG;IAC1D,YAAY,CAAC,EAAE;QACb,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;KAC9B,CAAC;CACH,CAAC;AAEF,wBAAsB,6BAA6B,CACjD,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAYlC,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAMnD,KAAK,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,GAAG;IAC1D,YAAY,CAAC,EAAE;QACb,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;KAC9B,CAAC;CACH,CAAC;AAEF,wBAAsB,6BAA6B,CACjD,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,oBAAoB,mBAuO9B"}
|
|
@@ -36,6 +36,8 @@ async function browsingAgentUsingMasterAgent(task, page, options) {
|
|
|
36
36
|
provider: options.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER,
|
|
37
37
|
defaultModel: options.model || constants_1.DEFAULT_MODEL,
|
|
38
38
|
providerApiKey: constants_1.MODEL_API_KEYS[options.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER],
|
|
39
|
+
// we will be using google model for larger context window, in such cases 1 million tokens is not enough
|
|
40
|
+
maxTokens: options.modelProvider === "google" ? 3000000 : 1000000,
|
|
39
41
|
});
|
|
40
42
|
const actions = new actions_1.PlaywrightActions(page);
|
|
41
43
|
const tools = actions.getActionSchemas();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/utils.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAWvD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/utils.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAWvD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAK5C,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,MAAM,CAKhD;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,UAIvD;AAmDD;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,aAAa,GACvB,OAAO,CAAC,MAAM,CAAC,CA+BjB;AAyBD,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,IAAI,iBAiBxD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,QA6BjD;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAM1E;AAWD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,oBAAoB,GACrC,OAAO,CAAC,MAAM,CAAC,CA8CjB;AAED,wBAAsB,sBAAsB,CAAC,EAC3C,YAAiB,EACjB,IAAS,EACT,eAAoB,EACpB,gBAAqB,EACrB,UAAyC,GAC1C,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,8EASA"}
|
|
@@ -12,6 +12,7 @@ const api_1 = __importDefault(require("tsx/cjs/api"));
|
|
|
12
12
|
const logger_1 = require("../../bin/logger");
|
|
13
13
|
const context_1 = require("../../bin/utils/context");
|
|
14
14
|
const web_1 = require("../../bin/utils/platform/web");
|
|
15
|
+
const create_test_block_1 = require("../codegen/create-test-block");
|
|
15
16
|
const fix_ts_errors_1 = require("../codegen/fix-ts-errors");
|
|
16
17
|
const update_flow_1 = require("../codegen/update-flow");
|
|
17
18
|
function isRegExp(obj) {
|
|
@@ -31,25 +32,16 @@ exports.prepareBrowsingAgentTask = prepareBrowsingAgentTask;
|
|
|
31
32
|
*/
|
|
32
33
|
async function prepareFileForUpdateScenario(genConfig) {
|
|
33
34
|
const { specPath, testCase } = genConfig;
|
|
34
|
-
const { name
|
|
35
|
+
const { name } = testCase;
|
|
35
36
|
// update the test case with appropriate location for createTest
|
|
36
37
|
// TODO: reduce the payload for this LLM call. Only provide test file and page files which are used in the test block
|
|
37
38
|
// this will help with faster response
|
|
38
|
-
const [suggestion] = await (0, update_flow_1.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
- This method will help you execute given task.
|
|
45
|
-
- Given the task you need to decide the right file path and code block to place this method.
|
|
46
|
-
- The task should contain hints as in where to place this method.
|
|
47
|
-
- If there is no hint provided in the task, you can assume the method needs to be placed at the end of the test block.
|
|
48
|
-
- YOU NEED TO MANDATORILY USE "createTest" method to execute the task.
|
|
49
|
-
- Once the methods is placed in the right location with a task and playwright page provided, assume the task is done.
|
|
50
|
-
- You need to respond with file path, code block and updated code block where this method can be placed in order to accomplish the task`,
|
|
51
|
-
],
|
|
52
|
-
}, specPath, genConfig.options, false, false);
|
|
39
|
+
const [suggestion] = await (0, update_flow_1.appendCreateTestBlock)({
|
|
40
|
+
testCase,
|
|
41
|
+
file: specPath,
|
|
42
|
+
validateTypes: false,
|
|
43
|
+
options: genConfig.options,
|
|
44
|
+
});
|
|
53
45
|
const createTestFilePath = suggestion?.updatedFiles[0] || "";
|
|
54
46
|
console.log("appending to existing test block");
|
|
55
47
|
console.log("updated test file path", createTestFilePath);
|
|
@@ -69,21 +61,6 @@ async function prepareFileForUpdateScenario(genConfig) {
|
|
|
69
61
|
const updatedTestFileContent = newContentsWithTestOnly(testFileContent, testBlock, testBlock, parentDescribe?.getText() || "");
|
|
70
62
|
await fs_extra_1.default.writeFile(specPath, updatedTestFileContent);
|
|
71
63
|
}
|
|
72
|
-
/**
|
|
73
|
-
* Function to prepare test file for new scenarios for master agent to run
|
|
74
|
-
* @param {TestGenConfig} genConfig
|
|
75
|
-
*/
|
|
76
|
-
async function prepareFileForNewScenario(genConfig) {
|
|
77
|
-
const { specPath, testCase } = genConfig;
|
|
78
|
-
const { name, steps } = testCase;
|
|
79
|
-
console.log("creating new test block");
|
|
80
|
-
const mergedSteps = prepareBrowsingAgentTask(steps);
|
|
81
|
-
// TODO: this assumes that test code repo has `page` as the main entrypoint fixture
|
|
82
|
-
const testGenCodeBlock = createTestBlockForCreateTest(name, mergedSteps);
|
|
83
|
-
const existingContents = await fs_extra_1.default.readFile(specPath, "utf-8");
|
|
84
|
-
const newContents = `${existingContents}\n\n${testGenCodeBlock}`;
|
|
85
|
-
await fs_extra_1.default.writeFile(specPath, (0, web_1.addNewImport)(newContents, ["createTest"], "@empiricalrun/test-gen"));
|
|
86
|
-
}
|
|
87
64
|
/**
|
|
88
65
|
* Function to prepare test file for master agent to run
|
|
89
66
|
* @param {TestGenConfig} genConfig
|
|
@@ -99,16 +76,18 @@ async function prepareFileForMasterAgent(genConfig) {
|
|
|
99
76
|
const fileContentWithImports = (0, web_1.addNewImport)("", ["test", "expect"], (0, web_1.getFixtureImportPath)(specPath));
|
|
100
77
|
await fs_extra_1.default.writeFile(specPath, fileContentWithImports, "utf-8");
|
|
101
78
|
}
|
|
102
|
-
let createTestFilePath = specPath;
|
|
103
79
|
const existingContents = await fs_extra_1.default.readFile(specPath, "utf-8");
|
|
104
80
|
const { testBlock } = (0, web_1.getTypescriptTestBlock)(name, existingContents);
|
|
105
|
-
if (testBlock) {
|
|
106
|
-
await
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
81
|
+
if (!testBlock) {
|
|
82
|
+
const newTestBlock = await (0, create_test_block_1.createEmptyTestCaseBlock)({
|
|
83
|
+
testCase: genConfig.testCase,
|
|
84
|
+
file: specPath,
|
|
85
|
+
options: genConfig.options,
|
|
86
|
+
});
|
|
87
|
+
await fs_extra_1.default.writeFile(specPath, `${existingContents} \n\n ${newTestBlock}`, "utf-8");
|
|
110
88
|
}
|
|
111
|
-
|
|
89
|
+
await prepareFileForUpdateScenario(genConfig);
|
|
90
|
+
return specPath;
|
|
112
91
|
}
|
|
113
92
|
exports.prepareFileForMasterAgent = prepareFileForMasterAgent;
|
|
114
93
|
function newContentsWithTestOnly(existingContents, originalTestBlock, updatedTestBlock, parentDescribeBlock) {
|
|
@@ -123,19 +102,6 @@ function newContentsWithTestOnly(existingContents, originalTestBlock, updatedTes
|
|
|
123
102
|
return existingContents.replace(parentDescribeBlock, describeMarkedAsOnly);
|
|
124
103
|
}
|
|
125
104
|
}
|
|
126
|
-
function createTestBlockForCreateTest(name, steps) {
|
|
127
|
-
return `
|
|
128
|
-
test.only("${name}", async ({page}) => {
|
|
129
|
-
${createTestGenBlock(steps)}
|
|
130
|
-
});
|
|
131
|
-
`;
|
|
132
|
-
}
|
|
133
|
-
function createTestGenBlock(steps) {
|
|
134
|
-
return `
|
|
135
|
-
await createTest(\`
|
|
136
|
-
${steps}\`, page);
|
|
137
|
-
`;
|
|
138
|
-
}
|
|
139
105
|
async function injectPwLocatorGenerator(page) {
|
|
140
106
|
const scriptResps = await Promise.all([
|
|
141
107
|
"https://assets-test.empirical.run/pw-selector.js",
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { TraceClient } from "@empiricalrun/llm";
|
|
2
|
+
import { TestCase, TestGenConfigOptions } from "../../types";
|
|
3
|
+
export declare function createEmptyTestCaseBlock({ testCase, file, options, trace, }: {
|
|
4
|
+
testCase: TestCase;
|
|
5
|
+
file: string;
|
|
6
|
+
options?: TestGenConfigOptions;
|
|
7
|
+
trace?: TraceClient;
|
|
8
|
+
}): Promise<string | undefined>;
|
|
9
|
+
//# sourceMappingURL=create-test-block.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-test-block.d.ts","sourceRoot":"","sources":["../../../src/agent/codegen/create-test-block.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAY3B,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAE7D,wBAAsB,wBAAwB,CAAC,EAC7C,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,+BAmDA"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createEmptyTestCaseBlock = void 0;
|
|
4
|
+
const llm_1 = require("@empiricalrun/llm");
|
|
5
|
+
const logger_1 = require("../../bin/logger");
|
|
6
|
+
const context_1 = require("../../bin/utils/context");
|
|
7
|
+
const web_1 = require("../../bin/utils/platform/web");
|
|
8
|
+
const constants_1 = require("../../constants");
|
|
9
|
+
const session_1 = require("../../session");
|
|
10
|
+
async function createEmptyTestCaseBlock({ testCase, file, options, trace, }) {
|
|
11
|
+
const logger = new logger_1.CustomLogger({ useReporter: false });
|
|
12
|
+
logger.log("Creating new test block");
|
|
13
|
+
const context = await (0, context_1.contextForGeneration)(file);
|
|
14
|
+
// TODO: move this to a common place
|
|
15
|
+
const session = (0, session_1.getSessionDetails)();
|
|
16
|
+
trace =
|
|
17
|
+
trace ||
|
|
18
|
+
llm_1.langfuseInstance.trace({
|
|
19
|
+
name: "update-test",
|
|
20
|
+
id: crypto.randomUUID(),
|
|
21
|
+
release: session.version,
|
|
22
|
+
tags: [
|
|
23
|
+
options?.metadata.projectName || "",
|
|
24
|
+
options?.metadata.environment || "",
|
|
25
|
+
].filter((s) => !!s),
|
|
26
|
+
});
|
|
27
|
+
const promptSpan = trace?.span({
|
|
28
|
+
name: "build-create-empty-test-case-prompt",
|
|
29
|
+
});
|
|
30
|
+
const prompt = await (0, llm_1.getPrompt)("create-empty-test-block", {
|
|
31
|
+
testFiles: context.codePrompt,
|
|
32
|
+
pageFiles: context.pomPrompt,
|
|
33
|
+
scenarioName: testCase.name,
|
|
34
|
+
scenario: testCase.steps.join("\n"),
|
|
35
|
+
scenarioFile: file,
|
|
36
|
+
});
|
|
37
|
+
promptSpan?.end({ output: { prompt } });
|
|
38
|
+
const llm = new llm_1.LLM({
|
|
39
|
+
trace,
|
|
40
|
+
provider: options?.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER,
|
|
41
|
+
defaultModel: options?.model || constants_1.DEFAULT_MODEL,
|
|
42
|
+
providerApiKey: constants_1.MODEL_API_KEYS[options?.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER],
|
|
43
|
+
});
|
|
44
|
+
const firstShotMessage = await llm.createChatCompletion({
|
|
45
|
+
messages: prompt,
|
|
46
|
+
modelParameters: {
|
|
47
|
+
...constants_1.DEFAULT_MODEL_PARAMETERS,
|
|
48
|
+
...options?.modelParameters,
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
const markdownRemoverSpan = trace?.span({
|
|
52
|
+
name: "remove-markdown-span",
|
|
53
|
+
});
|
|
54
|
+
let response = firstShotMessage?.content || "";
|
|
55
|
+
markdownRemoverSpan?.end({ output: { response } });
|
|
56
|
+
const { testBlock } = (0, web_1.getTypescriptTestBlock)(testCase.name, response);
|
|
57
|
+
console.log(`trace: ${trace?.getTraceUrl()}`);
|
|
58
|
+
return testBlock;
|
|
59
|
+
}
|
|
60
|
+
exports.createEmptyTestCaseBlock = createEmptyTestCaseBlock;
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
+
import { TraceClient } from "@empiricalrun/llm";
|
|
1
2
|
import { TestCase, TestGenConfigOptions } from "../../types";
|
|
2
3
|
type UpdatedTestCase = TestCase & {
|
|
3
4
|
updatedFiles: string[];
|
|
4
5
|
};
|
|
5
6
|
export declare function updateTest(testCase: TestCase, file: string, options: TestGenConfigOptions | undefined, logging?: boolean, validate?: boolean): Promise<UpdatedTestCase[]>;
|
|
7
|
+
export declare function appendCreateTestBlock({ testCase, file, options, trace, validateTypes, }: {
|
|
8
|
+
testCase: TestCase;
|
|
9
|
+
file: string;
|
|
10
|
+
options?: TestGenConfigOptions;
|
|
11
|
+
trace?: TraceClient;
|
|
12
|
+
validateTypes?: boolean;
|
|
13
|
+
}): Promise<UpdatedTestCase[]>;
|
|
6
14
|
export {};
|
|
7
15
|
//# sourceMappingURL=update-flow.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-flow.d.ts","sourceRoot":"","sources":["../../../src/agent/codegen/update-flow.ts"],"names":[],"mappings":"
|
|
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;AAmB3B,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAI7D,KAAK,eAAe,GAAG,QAAQ,GAAG;IAChC,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AA6GF,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,GAAG,SAAS,EACzC,OAAO,GAAE,OAAc,EACvB,QAAQ,GAAE,OAAc,GACvB,OAAO,CAAC,eAAe,EAAE,CAAC,CA6E5B;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,CAiE7B"}
|
|
@@ -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.updateTest = void 0;
|
|
6
|
+
exports.appendCreateTestBlock = exports.updateTest = void 0;
|
|
7
7
|
const llm_1 = require("@empiricalrun/llm");
|
|
8
8
|
const crypto_1 = __importDefault(require("crypto"));
|
|
9
9
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
@@ -15,59 +15,7 @@ const constants_1 = require("../../constants");
|
|
|
15
15
|
const session_1 = require("../../session");
|
|
16
16
|
const fix_ts_errors_1 = require("./fix-ts-errors");
|
|
17
17
|
const utils_1 = require("./utils");
|
|
18
|
-
async function
|
|
19
|
-
const logger = new logger_1.CustomLogger({ useReporter: logging });
|
|
20
|
-
const context = await (0, context_1.contextForGeneration)(file);
|
|
21
|
-
const { codePrompt, pomPrompt, testFileContent } = context;
|
|
22
|
-
const generatedTestCases = [];
|
|
23
|
-
logger.logEmptyLine();
|
|
24
|
-
const session = (0, session_1.getSessionDetails)();
|
|
25
|
-
const trace = llm_1.langfuseInstance.trace({
|
|
26
|
-
name: "update-test",
|
|
27
|
-
id: crypto_1.default.randomUUID(),
|
|
28
|
-
release: session.version,
|
|
29
|
-
tags: [
|
|
30
|
-
options?.metadata.projectName || "",
|
|
31
|
-
options?.metadata.environment || "",
|
|
32
|
-
].filter((s) => !!s),
|
|
33
|
-
});
|
|
34
|
-
trace.event({
|
|
35
|
-
name: "collate-files-as-text",
|
|
36
|
-
output: {
|
|
37
|
-
codePrompt,
|
|
38
|
-
pomPrompt,
|
|
39
|
-
testFileContent,
|
|
40
|
-
},
|
|
41
|
-
});
|
|
42
|
-
trace.update({ input: { testCase } });
|
|
43
|
-
const promptSpan = trace.span({
|
|
44
|
-
name: "update-scenario-prompt",
|
|
45
|
-
});
|
|
46
|
-
const promptName = "update-scenario";
|
|
47
|
-
const instruction = await (0, llm_1.getPrompt)(promptName, {
|
|
48
|
-
testFiles: codePrompt,
|
|
49
|
-
pageFiles: pomPrompt,
|
|
50
|
-
scenarioName: testCase.name,
|
|
51
|
-
scenarioSteps: testCase.steps.join("\n"),
|
|
52
|
-
scenarioFile: file,
|
|
53
|
-
}, 14);
|
|
54
|
-
promptSpan.end({ output: { instruction } });
|
|
55
|
-
const llm = new llm_1.LLM({
|
|
56
|
-
trace,
|
|
57
|
-
provider: options?.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER,
|
|
58
|
-
defaultModel: options?.model || constants_1.DEFAULT_MODEL,
|
|
59
|
-
providerApiKey: constants_1.MODEL_API_KEYS[options?.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER],
|
|
60
|
-
});
|
|
61
|
-
const firstShotMessage = await llm.createChatCompletion({
|
|
62
|
-
messages: instruction,
|
|
63
|
-
modelParameters: {
|
|
64
|
-
...constants_1.DEFAULT_MODEL_PARAMETERS,
|
|
65
|
-
...options?.modelParameters,
|
|
66
|
-
},
|
|
67
|
-
});
|
|
68
|
-
let response = firstShotMessage?.content || "";
|
|
69
|
-
logger.success("Test generated successfully!");
|
|
70
|
-
const fileChanges = (0, utils_1.extractTestUpdates)(response);
|
|
18
|
+
async function applyFileChanges({ validateTypes = true, trace, testCase, fileChanges, logger, testGenOptions, pomPrompt, codePrompt, }) {
|
|
71
19
|
await Promise.allSettled(fileChanges.map(async (fileChange) => {
|
|
72
20
|
if (!fileChange.filePath) {
|
|
73
21
|
return;
|
|
@@ -113,7 +61,7 @@ async function updateTest(testCase, file, options, logging = true, validate = tr
|
|
|
113
61
|
readWriteFileSpan.end({ output: { contents } });
|
|
114
62
|
}
|
|
115
63
|
// format and validate file change
|
|
116
|
-
if (
|
|
64
|
+
if (validateTypes) {
|
|
117
65
|
await (0, fix_ts_errors_1.validateAndFixTypescriptErrors)({
|
|
118
66
|
trace,
|
|
119
67
|
logger,
|
|
@@ -121,13 +69,77 @@ async function updateTest(testCase, file, options, logging = true, validate = tr
|
|
|
121
69
|
testCode: codePrompt,
|
|
122
70
|
pomCode: pomPrompt,
|
|
123
71
|
testCase: testCase,
|
|
124
|
-
options,
|
|
72
|
+
options: testGenOptions,
|
|
125
73
|
});
|
|
126
74
|
}
|
|
127
75
|
trace.event({ name: "format-file" });
|
|
128
76
|
await (0, web_1.formatCode)(fileChange.filePath);
|
|
129
77
|
logger.success(`${fileChange.filePath} file formatted successfully!`);
|
|
130
78
|
}));
|
|
79
|
+
}
|
|
80
|
+
async function updateTest(testCase, file, options, logging = true, validate = true) {
|
|
81
|
+
const logger = new logger_1.CustomLogger({ useReporter: logging });
|
|
82
|
+
const context = await (0, context_1.contextForGeneration)(file);
|
|
83
|
+
const { codePrompt, pomPrompt, testFileContent } = context;
|
|
84
|
+
const generatedTestCases = [];
|
|
85
|
+
logger.logEmptyLine();
|
|
86
|
+
const session = (0, session_1.getSessionDetails)();
|
|
87
|
+
const trace = llm_1.langfuseInstance.trace({
|
|
88
|
+
name: "update-test",
|
|
89
|
+
id: crypto_1.default.randomUUID(),
|
|
90
|
+
release: session.version,
|
|
91
|
+
tags: [
|
|
92
|
+
options?.metadata.projectName || "",
|
|
93
|
+
options?.metadata.environment || "",
|
|
94
|
+
].filter((s) => !!s),
|
|
95
|
+
});
|
|
96
|
+
trace.event({
|
|
97
|
+
name: "collate-files-as-text",
|
|
98
|
+
output: {
|
|
99
|
+
codePrompt,
|
|
100
|
+
pomPrompt,
|
|
101
|
+
testFileContent,
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
trace.update({ input: { testCase } });
|
|
105
|
+
const promptSpan = trace.span({
|
|
106
|
+
name: "update-scenario-prompt",
|
|
107
|
+
});
|
|
108
|
+
const promptName = "update-scenario";
|
|
109
|
+
const instruction = await (0, llm_1.getPrompt)(promptName, {
|
|
110
|
+
testFiles: codePrompt,
|
|
111
|
+
pageFiles: pomPrompt,
|
|
112
|
+
scenarioName: testCase.name,
|
|
113
|
+
scenarioSteps: testCase.steps.join("\n"),
|
|
114
|
+
scenarioFile: file,
|
|
115
|
+
}, 14);
|
|
116
|
+
promptSpan.end({ output: { instruction } });
|
|
117
|
+
const llm = new llm_1.LLM({
|
|
118
|
+
trace,
|
|
119
|
+
provider: options?.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER,
|
|
120
|
+
defaultModel: options?.model || constants_1.DEFAULT_MODEL,
|
|
121
|
+
providerApiKey: constants_1.MODEL_API_KEYS[options?.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER],
|
|
122
|
+
});
|
|
123
|
+
const firstShotMessage = await llm.createChatCompletion({
|
|
124
|
+
messages: instruction,
|
|
125
|
+
modelParameters: {
|
|
126
|
+
...constants_1.DEFAULT_MODEL_PARAMETERS,
|
|
127
|
+
...options?.modelParameters,
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
let response = firstShotMessage?.content || "";
|
|
131
|
+
logger.success("Test generated successfully!");
|
|
132
|
+
const fileChanges = (0, utils_1.extractTestUpdates)(response);
|
|
133
|
+
await applyFileChanges({
|
|
134
|
+
validateTypes: validate,
|
|
135
|
+
trace,
|
|
136
|
+
testCase,
|
|
137
|
+
fileChanges,
|
|
138
|
+
logger,
|
|
139
|
+
testGenOptions: options,
|
|
140
|
+
pomPrompt: pomPrompt,
|
|
141
|
+
codePrompt: codePrompt,
|
|
142
|
+
});
|
|
131
143
|
logger.log(`Trace: ${trace.getTraceUrl()}`);
|
|
132
144
|
generatedTestCases.push({
|
|
133
145
|
...testCase,
|
|
@@ -138,3 +150,69 @@ async function updateTest(testCase, file, options, logging = true, validate = tr
|
|
|
138
150
|
return generatedTestCases;
|
|
139
151
|
}
|
|
140
152
|
exports.updateTest = updateTest;
|
|
153
|
+
async function appendCreateTestBlock({ testCase, file, options, trace, validateTypes = true, }) {
|
|
154
|
+
const logger = new logger_1.CustomLogger({ useReporter: false });
|
|
155
|
+
logger.log("Appending create test block");
|
|
156
|
+
const context = await (0, context_1.contextForGeneration)(file);
|
|
157
|
+
const { codePrompt, pomPrompt } = context;
|
|
158
|
+
const generatedTestCases = [];
|
|
159
|
+
// TODO: move this to a common place
|
|
160
|
+
const session = (0, session_1.getSessionDetails)();
|
|
161
|
+
trace =
|
|
162
|
+
trace ||
|
|
163
|
+
llm_1.langfuseInstance.trace({
|
|
164
|
+
name: "append-create-test-block",
|
|
165
|
+
id: crypto_1.default.randomUUID(),
|
|
166
|
+
release: session.version,
|
|
167
|
+
tags: [
|
|
168
|
+
options?.metadata.projectName || "",
|
|
169
|
+
options?.metadata.environment || "",
|
|
170
|
+
].filter((s) => !!s),
|
|
171
|
+
});
|
|
172
|
+
const promptName = "append-create-test-block";
|
|
173
|
+
const promptSpan = trace.span({
|
|
174
|
+
name: "append-create-test-block-prompt",
|
|
175
|
+
});
|
|
176
|
+
const instruction = await (0, llm_1.getPrompt)(promptName, {
|
|
177
|
+
testFiles: codePrompt,
|
|
178
|
+
pageFiles: pomPrompt,
|
|
179
|
+
scenarioName: testCase.name,
|
|
180
|
+
scenarioSteps: testCase.steps.join("\n"),
|
|
181
|
+
scenarioFile: file,
|
|
182
|
+
});
|
|
183
|
+
promptSpan.end({ output: { instruction } });
|
|
184
|
+
const llm = new llm_1.LLM({
|
|
185
|
+
trace,
|
|
186
|
+
provider: options?.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER,
|
|
187
|
+
defaultModel: options?.model || constants_1.DEFAULT_MODEL,
|
|
188
|
+
providerApiKey: constants_1.MODEL_API_KEYS[options?.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER],
|
|
189
|
+
});
|
|
190
|
+
const firstShotMessage = await llm.createChatCompletion({
|
|
191
|
+
messages: instruction,
|
|
192
|
+
modelParameters: {
|
|
193
|
+
...constants_1.DEFAULT_MODEL_PARAMETERS,
|
|
194
|
+
...options?.modelParameters,
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
let response = firstShotMessage?.content || "";
|
|
198
|
+
const fileChanges = (0, utils_1.extractTestUpdates)(response);
|
|
199
|
+
await applyFileChanges({
|
|
200
|
+
trace,
|
|
201
|
+
testCase,
|
|
202
|
+
fileChanges,
|
|
203
|
+
logger,
|
|
204
|
+
testGenOptions: options,
|
|
205
|
+
pomPrompt: pomPrompt,
|
|
206
|
+
codePrompt: codePrompt,
|
|
207
|
+
validateTypes,
|
|
208
|
+
});
|
|
209
|
+
logger.log(`Trace: ${trace.getTraceUrl()}`);
|
|
210
|
+
generatedTestCases.push({
|
|
211
|
+
...testCase,
|
|
212
|
+
updatedFiles: fileChanges.map((f) => f.filePath),
|
|
213
|
+
});
|
|
214
|
+
trace.update({ input: { testCase }, output: { response } });
|
|
215
|
+
await (0, llm_1.flushAllTraces)();
|
|
216
|
+
return generatedTestCases;
|
|
217
|
+
}
|
|
218
|
+
exports.appendCreateTestBlock = appendCreateTestBlock;
|
package/dist/reporter/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/reporter/index.ts"],"names":[],"mappings":"AACA,OAAO,EAA4B,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAa5E,KAAK,kBAAkB,GAAG;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAKF,wBAAgB,WAAW,IAAI,QAAQ,GAAG,SAAS,CAUlD;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAGlE;AAED,qBAAa,sBAAsB;;IAE3B,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK1C,eAAe,CAAC,EACpB,eAAe,EACf,QAAQ,GACT,EAAE;QACD,eAAe,EAAE,MAAM,CAAC;QACxB,QAAQ,EAAE,MAAM,CAAC;KAClB;IA4CK,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA6B9C,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAUlD"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/reporter/index.ts"],"names":[],"mappings":";AACA,OAAO,EAA4B,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAa5E,KAAK,kBAAkB,GAAG;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAKF,wBAAgB,WAAW,IAAI,QAAQ,GAAG,SAAS,CAUlD;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAGlE;AAED,qBAAa,sBAAsB;;IAE3B,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK1C,eAAe,CAAC,EACpB,eAAe,EACf,QAAQ,GACT,EAAE;QACD,eAAe,EAAE,MAAM,CAAC;QACxB,QAAQ,EAAE,MAAM,CAAC;KAClB;IA4CK,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA6B9C,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAUlD"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -29,7 +29,9 @@ export type TestCase = {
|
|
|
29
29
|
steps: string[];
|
|
30
30
|
group: string;
|
|
31
31
|
};
|
|
32
|
-
export type PlaywrightActionGenerator = (page: Page
|
|
32
|
+
export type PlaywrightActionGenerator = (page: Page, options?: {
|
|
33
|
+
stateVariables: Record<string, any>;
|
|
34
|
+
}) => Action;
|
|
33
35
|
export type ActionSchema = OpenAI.Chat.Completions.ChatCompletionTool;
|
|
34
36
|
export type Action = {
|
|
35
37
|
name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC;IACzB,KAAK,EAAE,QAAQ,CAAC;IAChB,aAAa,EAAE,WAAW,CAAC;IAC3B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,QAAQ,EAAE;QACR,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;QACxB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,aAAa,GAAG,YAAY,CAAC;KAC3C,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC;IACzB,KAAK,EAAE,QAAQ,CAAC;IAChB,aAAa,EAAE,WAAW,CAAC;IAC3B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,QAAQ,EAAE;QACR,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;QACxB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,aAAa,GAAG,YAAY,CAAC;KAC3C,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,CACtC,IAAI,EAAE,IAAI,EACV,OAAO,CAAC,EAAE;IACR,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACrC,KACE,MAAM,CAAC;AAEZ,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC;AAEtE,MAAM,MAAM,MAAM,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC5E,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM,CAAC;CAC/E,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@empiricalrun/test-gen",
|
|
3
|
-
"version": "0.27.
|
|
3
|
+
"version": "0.27.10",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"registry": "https://registry.npmjs.org/",
|
|
6
6
|
"access": "public"
|
|
@@ -36,14 +36,15 @@
|
|
|
36
36
|
"picocolors": "^1.0.1",
|
|
37
37
|
"playwright": "^1.44.1",
|
|
38
38
|
"prettier": "^3.2.5",
|
|
39
|
+
"remove-markdown": "^0.5.5",
|
|
39
40
|
"sanitize-html": "^2.13.0",
|
|
40
41
|
"slugify": "^1.6.6",
|
|
41
42
|
"ts-morph": "^23.0.0",
|
|
42
43
|
"tsx": "^4.16.2",
|
|
43
44
|
"typescript": "^5.3.3",
|
|
44
45
|
"@empiricalrun/llm": "^0.9.2",
|
|
45
|
-
"@empiricalrun/r2-uploader": "^0.
|
|
46
|
-
"@empiricalrun/reporter": "^0.18.
|
|
46
|
+
"@empiricalrun/r2-uploader": "^0.3.0",
|
|
47
|
+
"@empiricalrun/reporter": "^0.18.1"
|
|
47
48
|
},
|
|
48
49
|
"devDependencies": {
|
|
49
50
|
"@types/detect-port": "^1.3.5",
|