@empiricalrun/test-gen 0.27.5 → 0.27.8
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 +23 -0
- package/dist/actions/assert.js +1 -1
- package/dist/actions/click.js +1 -1
- package/dist/actions/fill.js +1 -1
- package/dist/actions/goto.d.ts.map +1 -1
- package/dist/actions/goto.js +2 -1
- package/dist/actions/reload-page.d.ts.map +1 -1
- package/dist/actions/reload-page.js +2 -1
- package/dist/actions/utils/index.d.ts +1 -0
- package/dist/actions/utils/index.d.ts.map +1 -1
- package/dist/actions/utils/index.js +13 -2
- package/dist/agent/browsing/run.d.ts.map +1 -1
- package/dist/agent/browsing/run.js +2 -0
- package/dist/agent/browsing/utils.d.ts.map +1 -1
- package/dist/agent/browsing/utils.js +13 -10
- package/dist/agent/codegen/fix-ts-errors.d.ts +13 -0
- package/dist/agent/codegen/fix-ts-errors.d.ts.map +1 -0
- package/dist/agent/codegen/fix-ts-errors.js +76 -0
- package/dist/agent/codegen/run.d.ts.map +1 -1
- package/dist/agent/codegen/run.js +10 -57
- package/dist/agent/codegen/update-flow.d.ts +1 -1
- package/dist/agent/codegen/update-flow.d.ts.map +1 -1
- package/dist/agent/codegen/update-flow.js +20 -27
- package/dist/agent/codegen/utils.d.ts +19 -0
- package/dist/agent/codegen/utils.d.ts.map +1 -0
- package/dist/agent/codegen/utils.js +36 -0
- package/dist/agent/master/run.d.ts.map +1 -1
- package/dist/agent/master/run.js +3 -2
- package/dist/bin/index.js +6 -1
- package/dist/bin/utils/platform/web/index.d.ts +1 -0
- package/dist/bin/utils/platform/web/index.d.ts.map +1 -1
- package/dist/bin/utils/platform/web/index.js +17 -11
- package/dist/reporter/index.d.ts.map +1 -1
- package/dist/reporter/index.js +23 -11
- package/dist/uploader/index.d.ts +1 -0
- package/dist/uploader/index.d.ts.map +1 -1
- package/dist/uploader/index.js +17 -23
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @empiricalrun/test-gen
|
|
2
2
|
|
|
3
|
+
## 0.27.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 849ec6a: fix: trace and video not playing after generation
|
|
8
|
+
|
|
9
|
+
## 0.27.7
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- ae6e28a: fix: handle different image input for different llms and handle escape characters in llm response
|
|
14
|
+
- cf0a651: fix: master agent should generate code with correct page variable name
|
|
15
|
+
- b1825cf: fix: handle typescript errors and add tests
|
|
16
|
+
- Updated dependencies [ae6e28a]
|
|
17
|
+
- @empiricalrun/llm@0.9.2
|
|
18
|
+
|
|
19
|
+
## 0.27.6
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Updated dependencies [2f520d3]
|
|
24
|
+
- @empiricalrun/r2-uploader@0.2.0
|
|
25
|
+
|
|
3
26
|
## 0.27.5
|
|
4
27
|
|
|
5
28
|
### Patch Changes
|
package/dist/actions/assert.js
CHANGED
|
@@ -16,7 +16,7 @@ const assertTextVisibilityActionGenerator = (page) => {
|
|
|
16
16
|
},
|
|
17
17
|
// TODO: args transformer to be kept at a single place
|
|
18
18
|
template: (args, options) => {
|
|
19
|
-
return `await expect(
|
|
19
|
+
return `await expect(${(0, utils_1.getPageVarName)()}.${options.locator}).toBeVisible();`;
|
|
20
20
|
},
|
|
21
21
|
name: exports.PLAYWRIGHT_ASSERT_TEXT_VISIBILITY_ACTION_NAME,
|
|
22
22
|
schema: {
|
package/dist/actions/click.js
CHANGED
|
@@ -18,7 +18,7 @@ const clickActionGenerator = (page) => {
|
|
|
18
18
|
},
|
|
19
19
|
// TODO: args transformer to be kept at a single place
|
|
20
20
|
template: (args, options) => {
|
|
21
|
-
return `await
|
|
21
|
+
return `await ${(0, utils_1.getPageVarName)()}.${options.locator}.click();`;
|
|
22
22
|
},
|
|
23
23
|
name: exports.PLAYWRIGHT_CLICK_ACTION_NAME,
|
|
24
24
|
schema: {
|
package/dist/actions/fill.js
CHANGED
|
@@ -17,7 +17,7 @@ const fillActionGenerator = (page) => {
|
|
|
17
17
|
},
|
|
18
18
|
// TODO: args transformer to be kept at a single place
|
|
19
19
|
template: (args, options) => {
|
|
20
|
-
return `await
|
|
20
|
+
return `await ${(0, utils_1.getPageVarName)()}.${options.locator}.fill("${args.text}");`;
|
|
21
21
|
},
|
|
22
22
|
name: exports.PLAYWRIGHT_FILL_ACTION_NAME,
|
|
23
23
|
schema: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"goto.d.ts","sourceRoot":"","sources":["../../src/actions/goto.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"goto.d.ts","sourceRoot":"","sources":["../../src/actions/goto.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAIrD,eAAO,MAAM,2BAA2B,cAAc,CAAC;AAEvD,eAAO,MAAM,mBAAmB,EAAE,yBAqCjC,CAAC"}
|
package/dist/actions/goto.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.gotoActionGenerator = exports.PLAYWRIGHT_GOTO_ACTION_NAME = void 0;
|
|
4
4
|
const utils_1 = require("../agent/browsing/utils");
|
|
5
5
|
const constants_1 = require("./constants");
|
|
6
|
+
const utils_2 = require("./utils");
|
|
6
7
|
exports.PLAYWRIGHT_GOTO_ACTION_NAME = "page_goto";
|
|
7
8
|
const gotoActionGenerator = (page) => {
|
|
8
9
|
return {
|
|
@@ -15,7 +16,7 @@ const gotoActionGenerator = (page) => {
|
|
|
15
16
|
// TODO: args transformer to be kept at a single place
|
|
16
17
|
template: (args) => {
|
|
17
18
|
const url = args.url;
|
|
18
|
-
const templ = `await
|
|
19
|
+
const templ = `await ${(0, utils_2.getPageVarName)()}.goto("${url}");`;
|
|
19
20
|
return templ;
|
|
20
21
|
},
|
|
21
22
|
name: exports.PLAYWRIGHT_GOTO_ACTION_NAME,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reload-page.d.ts","sourceRoot":"","sources":["../../src/actions/reload-page.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"reload-page.d.ts","sourceRoot":"","sources":["../../src/actions/reload-page.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAIrD,eAAO,MAAM,6BAA6B,gBAAgB,CAAC;AAE3D,eAAO,MAAM,qBAAqB,EAAE,yBA+BnC,CAAC"}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.reloadActionGenerator = exports.PLAYWRIGHT_RELOAD_ACTION_NAME = void 0;
|
|
4
4
|
const utils_1 = require("../agent/browsing/utils");
|
|
5
5
|
const constants_1 = require("./constants");
|
|
6
|
+
const utils_2 = require("./utils");
|
|
6
7
|
exports.PLAYWRIGHT_RELOAD_ACTION_NAME = "page_reload";
|
|
7
8
|
const reloadActionGenerator = (page) => {
|
|
8
9
|
return {
|
|
@@ -12,7 +13,7 @@ const reloadActionGenerator = (page) => {
|
|
|
12
13
|
await (0, utils_1.injectPwLocatorGenerator)(page);
|
|
13
14
|
},
|
|
14
15
|
template: () => {
|
|
15
|
-
const templ = `await
|
|
16
|
+
const templ = `await ${(0, utils_2.getPageVarName)()}.reload();`;
|
|
16
17
|
return templ;
|
|
17
18
|
},
|
|
18
19
|
name: exports.PLAYWRIGHT_RELOAD_ACTION_NAME,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/actions/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,UAAU,EAAE,GAAG,CAAC;QAChB,MAAM,EAAE,GAAG,CAAC;KACb;CACF;AAED,wBAAsB,oCAAoC,CACxD,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/actions/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,UAAU,EAAE,GAAG,CAAC;QAChB,MAAM,EAAE,GAAG,CAAC;KACb;CACF;AAED,wBAAsB,oCAAoC,CACxD,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,IAAI,gBAwBX;AAED,wBAAgB,cAAc,WAG7B"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getPlaywrightLocatorUsingCssSelector = void 0;
|
|
3
|
+
exports.getPageVarName = exports.getPlaywrightLocatorUsingCssSelector = void 0;
|
|
4
4
|
async function getPlaywrightLocatorUsingCssSelector(cssSelector, page) {
|
|
5
5
|
// TODO: analyse other solutions than just css. Also find other solutions to support :has-text -> prompting ?
|
|
6
6
|
// jquery doesnt support :has-text. neither css. Only playwright locator supports this selector though.
|
|
@@ -9,7 +9,13 @@ async function getPlaywrightLocatorUsingCssSelector(cssSelector, page) {
|
|
|
9
9
|
.replaceAll(":text", ":contains");
|
|
10
10
|
return await page.evaluate((locator) => {
|
|
11
11
|
const elements = window.jQuery(locator.cssForJq);
|
|
12
|
-
let
|
|
12
|
+
let elIdx = 0;
|
|
13
|
+
Array.from(elements).forEach((el, i) => {
|
|
14
|
+
if (window.jQuery(el).is(":visible")) {
|
|
15
|
+
elIdx = i;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
let selectedElem = elements[elIdx];
|
|
13
19
|
if (!selectedElem) {
|
|
14
20
|
throw Error(`Unable to find element, css: ${locator.css}`);
|
|
15
21
|
}
|
|
@@ -17,3 +23,8 @@ async function getPlaywrightLocatorUsingCssSelector(cssSelector, page) {
|
|
|
17
23
|
}, { css: cssSelector, cssForJq: sanitizedCssSelectorForJQuery });
|
|
18
24
|
}
|
|
19
25
|
exports.getPlaywrightLocatorUsingCssSelector = getPlaywrightLocatorUsingCssSelector;
|
|
26
|
+
function getPageVarName() {
|
|
27
|
+
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
|
28
|
+
return process.env.PAGE_VAR_NAME || "page";
|
|
29
|
+
}
|
|
30
|
+
exports.getPageVarName = getPageVarName;
|
|
@@ -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;;;;OAIG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAsB,6BAA6B,CAAC,EAClD,YAAY,EACZ,gBAAgB,GACjB,EAAE,iBAAiB,iBAuDnB"}
|
|
@@ -35,6 +35,7 @@ async function generateTestsUsingMasterAgent({ testFilePath, filePathToUpdate, }
|
|
|
35
35
|
const playwrightConfig = await (0, utils_2.readPlaywrightConfig)();
|
|
36
36
|
// detect the playwright project name for the given test file and playwright config
|
|
37
37
|
const project = await (0, utils_2.detectProjectName)(testFilePath, playwrightConfig);
|
|
38
|
+
const pageVar = await (0, web_1.getPageVariableNameFromCreateTest)(testFilePath);
|
|
38
39
|
console.log(`Detected playwright project name: ${project}`);
|
|
39
40
|
// run playwright test which will internally run the master agent
|
|
40
41
|
let command = `npx playwright test ${testFilePath} --retries 0 --project ${project} --timeout 0`;
|
|
@@ -49,6 +50,7 @@ async function generateTestsUsingMasterAgent({ testFilePath, filePathToUpdate, }
|
|
|
49
50
|
PW_TEST_HTML_REPORT_OPEN: "never",
|
|
50
51
|
// pass the test gen token so that the agent has the same configuration as cli
|
|
51
52
|
TEST_GEN_TOKEN: (0, utils_1.getTestConfigCliArg)(),
|
|
53
|
+
PAGE_VAR_NAME: pageVar || "page",
|
|
52
54
|
},
|
|
53
55
|
});
|
|
54
56
|
}
|
|
@@ -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;
|
|
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;AAI5C,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,MAAM,CAKhD;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,UAIvD;AAqFD;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,aAAa,GACvB,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAwCD,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"}
|
|
@@ -10,7 +10,9 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
|
10
10
|
const minimatch_1 = require("minimatch");
|
|
11
11
|
const api_1 = __importDefault(require("tsx/cjs/api"));
|
|
12
12
|
const logger_1 = require("../../bin/logger");
|
|
13
|
+
const context_1 = require("../../bin/utils/context");
|
|
13
14
|
const web_1 = require("../../bin/utils/platform/web");
|
|
15
|
+
const fix_ts_errors_1 = require("../codegen/fix-ts-errors");
|
|
14
16
|
const update_flow_1 = require("../codegen/update-flow");
|
|
15
17
|
function isRegExp(obj) {
|
|
16
18
|
return (obj instanceof RegExp ||
|
|
@@ -47,24 +49,25 @@ async function prepareFileForUpdateScenario(genConfig) {
|
|
|
47
49
|
- Once the methods is placed in the right location with a task and playwright page provided, assume the task is done.
|
|
48
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`,
|
|
49
51
|
],
|
|
50
|
-
}, specPath, genConfig.options, false);
|
|
52
|
+
}, specPath, genConfig.options, false, false);
|
|
51
53
|
const createTestFilePath = suggestion?.updatedFiles[0] || "";
|
|
52
54
|
console.log("appending to existing test block");
|
|
53
55
|
console.log("updated test file path", createTestFilePath);
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
await fs_extra_1.default.writeFile(createTestFilePath, (0, web_1.addNewImport)(await fs_extra_1.default.readFile(createTestFilePath, "utf-8"), ["createTest"], "@empiricalrun/test-gen"));
|
|
57
|
+
const { codePrompt, pomPrompt } = await (0, context_1.contextForGeneration)(createTestFilePath);
|
|
58
|
+
await (0, fix_ts_errors_1.validateAndFixTypescriptErrors)({
|
|
59
|
+
file: createTestFilePath,
|
|
60
|
+
testCode: codePrompt,
|
|
61
|
+
pomCode: pomPrompt,
|
|
62
|
+
testCase: testCase,
|
|
63
|
+
options: genConfig.options,
|
|
64
|
+
});
|
|
60
65
|
const testFileContent = await fs_extra_1.default.readFile(specPath, "utf-8");
|
|
61
66
|
const { testBlock, testNode } = (0, web_1.getTypescriptTestBlock)(name, testFileContent);
|
|
62
67
|
const parentDescribe = (0, web_1.findFirstSerialDescribeBlock)(testNode);
|
|
63
68
|
// add test.only / describe.only to the spec file so that only that block is executed
|
|
64
69
|
const updatedTestFileContent = newContentsWithTestOnly(testFileContent, testBlock, testBlock, parentDescribe?.getText() || "");
|
|
65
|
-
await fs_extra_1.default.writeFile(specPath,
|
|
66
|
-
? (0, web_1.addNewImport)(updatedTestFileContent, ["createTest"], "@empiricalrun/test-gen")
|
|
67
|
-
: updatedTestFileContent);
|
|
70
|
+
await fs_extra_1.default.writeFile(specPath, updatedTestFileContent);
|
|
68
71
|
}
|
|
69
72
|
/**
|
|
70
73
|
* Function to prepare test file for new scenarios for master agent to run
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { TraceClient } from "@empiricalrun/llm";
|
|
2
|
+
import { CustomLogger } from "../../bin/logger";
|
|
3
|
+
import { TestCase, TestGenConfigOptions } from "../../types";
|
|
4
|
+
export declare function validateAndFixTypescriptErrors({ trace, logger, file, testCode, pomCode, testCase, options, }: {
|
|
5
|
+
trace?: TraceClient;
|
|
6
|
+
logger?: CustomLogger;
|
|
7
|
+
file: string;
|
|
8
|
+
testCode: string;
|
|
9
|
+
pomCode: string;
|
|
10
|
+
testCase: TestCase;
|
|
11
|
+
options?: TestGenConfigOptions;
|
|
12
|
+
}): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=fix-ts-errors.d.ts.map
|
|
@@ -0,0 +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,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,OAAO,GACR,EAAE;IACD,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC,iBAoEA"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.validateAndFixTypescriptErrors = void 0;
|
|
7
|
+
const llm_1 = require("@empiricalrun/llm");
|
|
8
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
9
|
+
const logger_1 = require("../../bin/logger");
|
|
10
|
+
const web_1 = require("../../bin/utils/platform/web");
|
|
11
|
+
const constants_1 = require("../../constants");
|
|
12
|
+
async function validateAndFixTypescriptErrors({ trace, logger = new logger_1.CustomLogger(), file, testCode, pomCode, testCase, options, }) {
|
|
13
|
+
const validateTypesSpan = trace?.span({ name: "detect-type-errors-in-file" });
|
|
14
|
+
logger.log("Validating types...");
|
|
15
|
+
let errors = (0, web_1.validateTypescript)(file);
|
|
16
|
+
validateTypesSpan?.end({ output: { errors } });
|
|
17
|
+
if (!errors.length) {
|
|
18
|
+
logger.success("Found no type issues!");
|
|
19
|
+
}
|
|
20
|
+
const maxIteration = 2;
|
|
21
|
+
let counter = 0;
|
|
22
|
+
while (errors.length > 0) {
|
|
23
|
+
const fileContent = await fs_extra_1.default.readFile(file, "utf-8");
|
|
24
|
+
counter += 1;
|
|
25
|
+
if (counter > maxIteration) {
|
|
26
|
+
trace?.event({ name: "code-fix-iteration-max-out" });
|
|
27
|
+
logger.error([
|
|
28
|
+
`Unable to fix typescript errors. Please review ${file} manually and fix the typescript errors.`,
|
|
29
|
+
`Trace: ${trace?.getTraceUrl()}`,
|
|
30
|
+
].join("\n"));
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
trace?.event({ name: "Found errors fixing" });
|
|
34
|
+
logger.warn("Found few errors while validating types:");
|
|
35
|
+
errors.forEach((e) => logger.warn(e));
|
|
36
|
+
logger.log("Trying to fix above errors...");
|
|
37
|
+
const promptSpan = trace?.span({ name: "fix-type-errors-prompt" });
|
|
38
|
+
const instruction = await (0, llm_1.getPrompt)("fix-file-errors-ts", {
|
|
39
|
+
testFiles: testCode || "",
|
|
40
|
+
pageFiles: pomCode || "",
|
|
41
|
+
scenarioFile: file,
|
|
42
|
+
errors: errors,
|
|
43
|
+
fileContent: fileContent,
|
|
44
|
+
scenaioName: testCase.name,
|
|
45
|
+
});
|
|
46
|
+
promptSpan?.end({ output: { instruction } });
|
|
47
|
+
const llm = new llm_1.LLM({
|
|
48
|
+
trace,
|
|
49
|
+
provider: options?.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER,
|
|
50
|
+
defaultModel: options?.model || constants_1.DEFAULT_MODEL,
|
|
51
|
+
providerApiKey: constants_1.MODEL_API_KEYS[options?.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER],
|
|
52
|
+
});
|
|
53
|
+
const message = await llm.createChatCompletion({
|
|
54
|
+
messages: instruction,
|
|
55
|
+
modelParameters: {
|
|
56
|
+
...constants_1.DEFAULT_MODEL_PARAMETERS,
|
|
57
|
+
...options?.modelParameters,
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
const response = message?.content || "";
|
|
61
|
+
const readWriteFileSpan = trace?.span({ name: "write-to-file" });
|
|
62
|
+
await fs_extra_1.default.writeFile(file, response, "utf-8");
|
|
63
|
+
readWriteFileSpan?.end({ output: { response } });
|
|
64
|
+
trace?.event({ name: "lint-file" });
|
|
65
|
+
await (0, web_1.lintErrors)(file);
|
|
66
|
+
const validateTypesSpan = trace?.span({
|
|
67
|
+
name: "detect-type-errors-in-file",
|
|
68
|
+
});
|
|
69
|
+
errors = (0, web_1.validateTypescript)(file);
|
|
70
|
+
validateTypesSpan?.end({ output: { errors } });
|
|
71
|
+
if (!errors.length) {
|
|
72
|
+
logger.success("Found no type issues!");
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
exports.validateAndFixTypescriptErrors = validateAndFixTypescriptErrors;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/codegen/run.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/codegen/run.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAI7D,wBAAsB,YAAY,CAChC,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,QAAQ,EAAE,CAAC,CA+FrB"}
|
|
@@ -12,6 +12,7 @@ const context_1 = require("../../bin/utils/context");
|
|
|
12
12
|
const web_1 = require("../../bin/utils/platform/web");
|
|
13
13
|
const constants_1 = require("../../constants");
|
|
14
14
|
const session_1 = require("../../session");
|
|
15
|
+
const fix_ts_errors_1 = require("./fix-ts-errors");
|
|
15
16
|
const update_flow_1 = require("./update-flow");
|
|
16
17
|
async function generateTest(testCase, file, options) {
|
|
17
18
|
const logger = new logger_1.CustomLogger();
|
|
@@ -79,63 +80,15 @@ async function generateTest(testCase, file, options) {
|
|
|
79
80
|
logger.log("Linting generated code...");
|
|
80
81
|
trace.event({ name: "lint-file" });
|
|
81
82
|
await (0, web_1.lintErrors)(file);
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
while (errors.length > 0) {
|
|
92
|
-
const fileContent = fs_extra_1.default.readFileSync(file, "utf-8");
|
|
93
|
-
counter += 1;
|
|
94
|
-
if (counter > maxIteration) {
|
|
95
|
-
trace.event({ name: "code-fix-iteration-max-out" });
|
|
96
|
-
logger.error([
|
|
97
|
-
`Unable to fix typescript errors. Please review ${file} manually and fix the typescript errors.`,
|
|
98
|
-
`Run the test-gen command again, once errors are fixed.`,
|
|
99
|
-
`Trace: ${trace.getTraceUrl()}`,
|
|
100
|
-
].join("\n"));
|
|
101
|
-
break;
|
|
102
|
-
}
|
|
103
|
-
trace.event({ name: "Found errors fixing" });
|
|
104
|
-
logger.warn("Found few errors while validating types:");
|
|
105
|
-
errors.forEach((e) => logger.warn(e));
|
|
106
|
-
logger.log("Trying to fix above errors...");
|
|
107
|
-
const promptSpan = trace.span({ name: "fix-type-errors-prompt" });
|
|
108
|
-
const instruction = await (0, llm_1.getPrompt)("fix-file-errors-ts", {
|
|
109
|
-
testFiles: codePrompt || "",
|
|
110
|
-
pageFiles: pomPrompt || "",
|
|
111
|
-
scenarioFile: file,
|
|
112
|
-
errors: errors,
|
|
113
|
-
fileContent: fileContent,
|
|
114
|
-
scenaioName: testCase.name,
|
|
115
|
-
});
|
|
116
|
-
promptSpan.end({ output: { instruction } });
|
|
117
|
-
const message = await llm.createChatCompletion({
|
|
118
|
-
messages: instruction,
|
|
119
|
-
modelParameters: {
|
|
120
|
-
...constants_1.DEFAULT_MODEL_PARAMETERS,
|
|
121
|
-
...options.modelParameters,
|
|
122
|
-
},
|
|
123
|
-
});
|
|
124
|
-
response = message?.content || "";
|
|
125
|
-
const readWriteFileSpan = trace.span({ name: "write-to-file" });
|
|
126
|
-
await fs_extra_1.default.writeFile(file, response, "utf-8");
|
|
127
|
-
readWriteFileSpan.end({ output: { response } });
|
|
128
|
-
trace.event({ name: "lint-file" });
|
|
129
|
-
await (0, web_1.lintErrors)(file);
|
|
130
|
-
const validateTypesSpan = trace.span({
|
|
131
|
-
name: "detect-type-errors-in-file",
|
|
132
|
-
});
|
|
133
|
-
errors = (0, web_1.validateTypescript)(file);
|
|
134
|
-
validateTypesSpan.end({ output: { errors } });
|
|
135
|
-
if (!errors.length) {
|
|
136
|
-
logger.success("Found no type issues!");
|
|
137
|
-
}
|
|
138
|
-
}
|
|
83
|
+
await (0, fix_ts_errors_1.validateAndFixTypescriptErrors)({
|
|
84
|
+
trace,
|
|
85
|
+
logger,
|
|
86
|
+
file,
|
|
87
|
+
testCode: codePrompt,
|
|
88
|
+
pomCode: pomPrompt,
|
|
89
|
+
testCase: testCase,
|
|
90
|
+
options,
|
|
91
|
+
});
|
|
139
92
|
trace.event({ name: "format-file" });
|
|
140
93
|
await (0, web_1.formatCode)(file);
|
|
141
94
|
logger.success("File formatted successfully!");
|
|
@@ -2,6 +2,6 @@ import { TestCase, TestGenConfigOptions } from "../../types";
|
|
|
2
2
|
type UpdatedTestCase = TestCase & {
|
|
3
3
|
updatedFiles: string[];
|
|
4
4
|
};
|
|
5
|
-
export declare function updateTest(testCase: TestCase, file: string, options: TestGenConfigOptions | undefined, logging?: boolean): Promise<UpdatedTestCase[]>;
|
|
5
|
+
export declare function updateTest(testCase: TestCase, file: string, options: TestGenConfigOptions | undefined, logging?: boolean, validate?: boolean): Promise<UpdatedTestCase[]>;
|
|
6
6
|
export {};
|
|
7
7
|
//# 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":"AAwBA,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAI7D,KAAK,eAAe,GAAG,QAAQ,GAAG;IAChC,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AAEF,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,CAoJ5B"}
|
|
@@ -13,23 +13,9 @@ const context_1 = require("../../bin/utils/context");
|
|
|
13
13
|
const web_1 = require("../../bin/utils/platform/web");
|
|
14
14
|
const constants_1 = require("../../constants");
|
|
15
15
|
const session_1 = require("../../session");
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const regex = /<file_path>(.*?)<\/file_path>[\s\S]*?<old_code_block>([\s\S]*?)<\/old_code_block>[\s\S]*?<new_code_block>([\s\S]*?)<\/new_code_block>[\s\S]*?<change>([\s\S]*?)<\/change>/g;
|
|
20
|
-
let match;
|
|
21
|
-
while ((match = regex.exec(input)) !== null) {
|
|
22
|
-
const [, filePath, oldCode, newCode, reason] = match;
|
|
23
|
-
result.push({
|
|
24
|
-
filePath: filePath?.trim(),
|
|
25
|
-
oldCode: oldCode?.trim(),
|
|
26
|
-
newCode: newCode?.trim(),
|
|
27
|
-
reason: reason?.trim(),
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
return result;
|
|
31
|
-
}
|
|
32
|
-
async function updateTest(testCase, file, options, logging = true) {
|
|
16
|
+
const fix_ts_errors_1 = require("./fix-ts-errors");
|
|
17
|
+
const utils_1 = require("./utils");
|
|
18
|
+
async function updateTest(testCase, file, options, logging = true, validate = true) {
|
|
33
19
|
const logger = new logger_1.CustomLogger({ useReporter: logging });
|
|
34
20
|
const context = await (0, context_1.contextForGeneration)(file);
|
|
35
21
|
const { codePrompt, pomPrompt, testFileContent } = context;
|
|
@@ -81,7 +67,7 @@ async function updateTest(testCase, file, options, logging = true) {
|
|
|
81
67
|
});
|
|
82
68
|
let response = firstShotMessage?.content || "";
|
|
83
69
|
logger.success("Test generated successfully!");
|
|
84
|
-
const fileChanges =
|
|
70
|
+
const fileChanges = (0, utils_1.extractTestUpdates)(response);
|
|
85
71
|
await Promise.allSettled(fileChanges.map(async (fileChange) => {
|
|
86
72
|
if (!fileChange.filePath) {
|
|
87
73
|
return;
|
|
@@ -97,12 +83,8 @@ async function updateTest(testCase, file, options, logging = true) {
|
|
|
97
83
|
const { testBlock } = (0, web_1.getTypescriptTestBlock)(testCase?.name, contents);
|
|
98
84
|
contents = contents.replace(testBlock, `\n\n${strippedContent}`);
|
|
99
85
|
updatedContent = prependContent + contents;
|
|
100
|
-
await fs_extra_1.default.writeFile(
|
|
86
|
+
await fs_extra_1.default.writeFile(fileChange.filePath, updatedContent, "utf-8");
|
|
101
87
|
readWriteFileSpan.end({ output: { updatedContent } });
|
|
102
|
-
trace.event({ name: "format-file" });
|
|
103
|
-
await (0, web_1.lintErrors)(fileChange.filePath);
|
|
104
|
-
await (0, web_1.formatCode)(fileChange.filePath);
|
|
105
|
-
logger.success(`${fileChange.filePath} file formatted successfully!`);
|
|
106
88
|
}
|
|
107
89
|
else {
|
|
108
90
|
const readWriteFileSpan = trace.span({ name: "write-to-file" });
|
|
@@ -129,11 +111,22 @@ async function updateTest(testCase, file, options, logging = true) {
|
|
|
129
111
|
}
|
|
130
112
|
await fs_extra_1.default.writeFile(fileChange.filePath, contents, "utf-8");
|
|
131
113
|
readWriteFileSpan.end({ output: { contents } });
|
|
132
|
-
trace.event({ name: "format-file" });
|
|
133
|
-
await (0, web_1.lintErrors)(fileChange.filePath);
|
|
134
|
-
await (0, web_1.formatCode)(fileChange.filePath);
|
|
135
|
-
logger.success(`${fileChange.filePath} file formatted successfully!`);
|
|
136
114
|
}
|
|
115
|
+
// format and validate file change
|
|
116
|
+
if (validate) {
|
|
117
|
+
await (0, fix_ts_errors_1.validateAndFixTypescriptErrors)({
|
|
118
|
+
trace,
|
|
119
|
+
logger,
|
|
120
|
+
file: fileChange.filePath,
|
|
121
|
+
testCode: codePrompt,
|
|
122
|
+
pomCode: pomPrompt,
|
|
123
|
+
testCase: testCase,
|
|
124
|
+
options,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
trace.event({ name: "format-file" });
|
|
128
|
+
await (0, web_1.formatCode)(fileChange.filePath);
|
|
129
|
+
logger.success(`${fileChange.filePath} file formatted successfully!`);
|
|
137
130
|
}));
|
|
138
131
|
logger.log(`Trace: ${trace.getTraceUrl()}`);
|
|
139
132
|
generatedTestCases.push({
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* method to extract file path and code updates for the LLM response of update flow
|
|
4
|
+
* @export
|
|
5
|
+
* @param {string} input
|
|
6
|
+
* @return {*} {({
|
|
7
|
+
* filePath: string | undefined;
|
|
8
|
+
* oldCode: string | undefined;
|
|
9
|
+
* newCode: string | undefined;
|
|
10
|
+
* reason: string | undefined;
|
|
11
|
+
* }[])}
|
|
12
|
+
*/
|
|
13
|
+
export declare function extractTestUpdates(input: string): {
|
|
14
|
+
filePath: string | undefined;
|
|
15
|
+
oldCode: string | undefined;
|
|
16
|
+
newCode: string | undefined;
|
|
17
|
+
reason: string | undefined;
|
|
18
|
+
}[];
|
|
19
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/agent/codegen/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG;IACjD,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,CAqBF"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractTestUpdates = void 0;
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* method to extract file path and code updates for the LLM response of update flow
|
|
7
|
+
* @export
|
|
8
|
+
* @param {string} input
|
|
9
|
+
* @return {*} {({
|
|
10
|
+
* filePath: string | undefined;
|
|
11
|
+
* oldCode: string | undefined;
|
|
12
|
+
* newCode: string | undefined;
|
|
13
|
+
* reason: string | undefined;
|
|
14
|
+
* }[])}
|
|
15
|
+
*/
|
|
16
|
+
function extractTestUpdates(input) {
|
|
17
|
+
const result = [];
|
|
18
|
+
// TODO: use better structure for this. Do not kill me for this please.
|
|
19
|
+
const regex = /<file_path>(.*?)<\/file_path>[\s\S]*?<old_code_block>([\s\S]*?)<\/old_code_block>[\s\S]*?<new_code_block>([\s\S]*?)<\/new_code_block>[\s\S]*?<change>([\s\S]*?)<\/change>/g;
|
|
20
|
+
let match;
|
|
21
|
+
// sometimes LLM responds with single backslashes instead of double backslashe for escapes
|
|
22
|
+
// we only have a scenario of double quotes being escaped.
|
|
23
|
+
// eslint-disable-next-line no-useless-escape, prettier/prettier
|
|
24
|
+
input = input.replaceAll(' \"', ' \\"').replaceAll('\" ', '\\" ');
|
|
25
|
+
while ((match = regex.exec(input)) !== null) {
|
|
26
|
+
const [, filePath, oldCode, newCode, reason] = match;
|
|
27
|
+
result.push({
|
|
28
|
+
filePath: filePath?.trim(),
|
|
29
|
+
oldCode: oldCode?.trim(),
|
|
30
|
+
newCode: newCode?.trim(),
|
|
31
|
+
reason: reason?.trim(),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
exports.extractTestUpdates = extractTestUpdates;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/master/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,GAAG,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/master/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,GAAG,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhE,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AASlC,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,KAAK,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAE1D,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,IAAI,EACV,eAAe,EAAE,MAAM,EAAE,EACzB,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,oBAAoB,gBAyE9B"}
|
package/dist/agent/master/run.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.masterAgent = void 0;
|
|
4
4
|
const llm_1 = require("@empiricalrun/llm");
|
|
5
|
+
const vision_1 = require("@empiricalrun/llm/vision");
|
|
5
6
|
const done_1 = require("../../actions/done");
|
|
6
7
|
const next_task_1 = require("../../actions/next-task");
|
|
7
8
|
const constants_1 = require("../../constants");
|
|
@@ -12,7 +13,7 @@ async function masterAgent(task, page, executedActions, trace, llm, options) {
|
|
|
12
13
|
const buffer = await page.screenshot({ fullPage: true });
|
|
13
14
|
const testGenReporter = new reporter_1.TestGenUpdatesReporter();
|
|
14
15
|
const testGenSnapshotUpdatePromise = testGenReporter.sendCurrentView(buffer);
|
|
15
|
-
const pageScreenshot =
|
|
16
|
+
const pageScreenshot = buffer.toString("base64");
|
|
16
17
|
const promptMessages = await (0, llm_1.getPrompt)("test-gen", {
|
|
17
18
|
task,
|
|
18
19
|
executedActions: executedActions.map((a) => a).join("\n"),
|
|
@@ -29,7 +30,7 @@ async function masterAgent(task, page, executedActions, trace, llm, options) {
|
|
|
29
30
|
{
|
|
30
31
|
type: "image_url",
|
|
31
32
|
image_url: {
|
|
32
|
-
url: pageScreenshot,
|
|
33
|
+
url: (0, vision_1.imageFormatForProvider)(options.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER, pageScreenshot),
|
|
33
34
|
},
|
|
34
35
|
},
|
|
35
36
|
];
|
package/dist/bin/index.js
CHANGED
|
@@ -61,7 +61,12 @@ async function runAgent(testGenConfig) {
|
|
|
61
61
|
sessionId: testGenConfig.options?.metadata.testSessionId,
|
|
62
62
|
generationId: testGenConfig.options?.metadata.generationId,
|
|
63
63
|
});
|
|
64
|
-
|
|
64
|
+
try {
|
|
65
|
+
await runAgent(testGenConfig);
|
|
66
|
+
}
|
|
67
|
+
catch (e) {
|
|
68
|
+
logger.error("Failed to run agent for the scenario", e);
|
|
69
|
+
}
|
|
65
70
|
// TODO: move these reporters to a better lifecycle
|
|
66
71
|
await (0, ci_1.reportOnCI)(testGenConfig.testCase);
|
|
67
72
|
await (0, llm_1.flushAllTraces)();
|
|
@@ -42,5 +42,6 @@ export declare function formatCode(filePath: string): Promise<void>;
|
|
|
42
42
|
export declare function addNewImport(contents: string, modules: string[], pkg: string): string;
|
|
43
43
|
export declare function removeTestOnly(filePath: string): Promise<void>;
|
|
44
44
|
export declare function getFixtureImportPath(filePath: string): string;
|
|
45
|
+
export declare function getPageVariableNameFromCreateTest(filePath: string): Promise<string | undefined>;
|
|
45
46
|
export declare function replaceCreateTestWithNewCode(filePath: string, contents: string, generatedCode: string): string;
|
|
46
47
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/bin/utils/platform/web/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAqB,IAAI,EAAuB,MAAM,UAAU,CAAC;AAGxE;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GACd;IACD,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,QAAQ,EAAE,IAAI,GAAG,SAAS,CAAC;CAC5B,CAeA;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,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/bin/utils/platform/web/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAqB,IAAI,EAAuB,MAAM,UAAU,CAAC;AAGxE;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GACd;IACD,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,QAAQ,EAAE,IAAI,GAAG,SAAS,CAAC;CAC5B,CAeA;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,mCAUjB;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,+BAmBvE;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,UA0CtB"}
|
|
@@ -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.replaceCreateTestWithNewCode = exports.getFixtureImportPath = exports.removeTestOnly = exports.addNewImport = exports.formatCode = exports.lintErrors = exports.stripAndPrependImports = exports.validateTypescript = exports.appendToTestBlock = exports.findFirstSerialDescribeBlock = exports.getTypescriptTestBlock = void 0;
|
|
6
|
+
exports.replaceCreateTestWithNewCode = exports.getPageVariableNameFromCreateTest = exports.getFixtureImportPath = exports.removeTestOnly = exports.addNewImport = exports.formatCode = exports.lintErrors = exports.stripAndPrependImports = exports.validateTypescript = exports.appendToTestBlock = exports.findFirstSerialDescribeBlock = exports.getTypescriptTestBlock = void 0;
|
|
7
7
|
const eslint_1 = require("eslint");
|
|
8
8
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
9
9
|
const prettier_1 = __importDefault(require("prettier"));
|
|
@@ -96,16 +96,6 @@ function validateTypescript(filePath) {
|
|
|
96
96
|
const syntacticDiagnostics = program.getSyntacticDiagnostics(sourceFile);
|
|
97
97
|
if (syntacticDiagnostics.length > 0) {
|
|
98
98
|
syntacticDiagnostics.forEach((diagnostic) => {
|
|
99
|
-
// const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(
|
|
100
|
-
// diagnostic.start,
|
|
101
|
-
// );
|
|
102
|
-
// const message = ts.flattenDiagnosticMessageText(
|
|
103
|
-
// diagnostic.messageText,
|
|
104
|
-
// "\n",
|
|
105
|
-
// );
|
|
106
|
-
// logger.log(
|
|
107
|
-
// `${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`,
|
|
108
|
-
// );
|
|
109
99
|
if (typeof diagnostic.messageText === "string") {
|
|
110
100
|
errors.push(diagnostic.messageText);
|
|
111
101
|
}
|
|
@@ -188,6 +178,22 @@ function getFixtureImportPath(filePath) {
|
|
|
188
178
|
return fixturesPath;
|
|
189
179
|
}
|
|
190
180
|
exports.getFixtureImportPath = getFixtureImportPath;
|
|
181
|
+
async function getPageVariableNameFromCreateTest(filePath) {
|
|
182
|
+
const contents = await fs_extra_1.default.readFile(filePath, "utf-8");
|
|
183
|
+
const project = new ts_morph_1.Project();
|
|
184
|
+
const sourceFile = project.createSourceFile("test.ts", contents);
|
|
185
|
+
const createTestNode = sourceFile.getFirstDescendant((node) => !!(node.isKind(ts_morph_1.SyntaxKind.CallExpression) &&
|
|
186
|
+
node.getExpression().getText() === "createTest"));
|
|
187
|
+
if (!createTestNode) {
|
|
188
|
+
throw new Error("createTest not found in file");
|
|
189
|
+
}
|
|
190
|
+
const descendants = createTestNode?.getDescendants();
|
|
191
|
+
const descendentTexts = descendants.map((d) => d.getText());
|
|
192
|
+
const parameterSeparatorIdx = descendentTexts.findIndex((s) => s === ",");
|
|
193
|
+
const pageVariableName = descendentTexts[parameterSeparatorIdx + 1];
|
|
194
|
+
return pageVariableName;
|
|
195
|
+
}
|
|
196
|
+
exports.getPageVariableNameFromCreateTest = getPageVariableNameFromCreateTest;
|
|
191
197
|
function replaceCreateTestWithNewCode(filePath, contents, generatedCode) {
|
|
192
198
|
const project = new ts_morph_1.Project();
|
|
193
199
|
const sourceFile = project.createSourceFile("test.ts", contents);
|
|
@@ -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;
|
|
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/reporter/index.js
CHANGED
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.TestGenUpdatesReporter = exports.setReporterConfig = exports.getReporter = void 0;
|
|
7
7
|
const r2_uploader_1 = require("@empiricalrun/r2-uploader");
|
|
8
8
|
const reporter_1 = require("@empiricalrun/reporter");
|
|
9
|
-
const
|
|
9
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
10
10
|
const path_1 = __importDefault(require("path"));
|
|
11
11
|
const logger_1 = require("../bin/logger");
|
|
12
12
|
const uploader_1 = require("../uploader");
|
|
@@ -61,13 +61,23 @@ class TestGenUpdatesReporter {
|
|
|
61
61
|
videoUrls,
|
|
62
62
|
};
|
|
63
63
|
await Promise.allSettled([
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
64
|
+
...(videoUrls.length
|
|
65
|
+
? [
|
|
66
|
+
reporter?.report(new reporter_1.ProcessLogMessageBuilder({
|
|
67
|
+
message: JSON.stringify(message),
|
|
68
|
+
})),
|
|
69
|
+
]
|
|
70
|
+
: []),
|
|
71
|
+
...(traceFiles.length
|
|
72
|
+
? [
|
|
73
|
+
reporter?.report(new reporter_1.ProcessLogMessageBuilder({
|
|
74
|
+
message: JSON.stringify({
|
|
75
|
+
type: "trace",
|
|
76
|
+
traceFiles,
|
|
77
|
+
}),
|
|
78
|
+
})),
|
|
79
|
+
]
|
|
80
|
+
: []),
|
|
71
81
|
]);
|
|
72
82
|
}
|
|
73
83
|
catch (err) {
|
|
@@ -77,8 +87,10 @@ class TestGenUpdatesReporter {
|
|
|
77
87
|
}
|
|
78
88
|
async sendCurrentView(buffer) {
|
|
79
89
|
// upload current screenshot to r2 and report it to reporter
|
|
80
|
-
|
|
81
|
-
|
|
90
|
+
if (!fs_extra_1.default.existsSync(path_1.default.join(process.cwd(), "gen-assets"))) {
|
|
91
|
+
await fs_extra_1.default.mkdir((process.cwd(), "gen-assets"));
|
|
92
|
+
}
|
|
93
|
+
await fs_extra_1.default.writeFile(path_1.default.join(process.cwd(), "gen-assets", `current-view-${Date.now()}.png`), buffer);
|
|
82
94
|
const uploadDir = (0, uploader_1.getUploadPathForRun)(reporterConfig?.projectRepoName);
|
|
83
95
|
const files = await (0, r2_uploader_1.uploadDirectory)({
|
|
84
96
|
sourceDir: path_1.default.join(process.cwd(), "gen-assets"),
|
|
@@ -91,7 +103,7 @@ class TestGenUpdatesReporter {
|
|
|
91
103
|
await getReporter()?.report(new reporter_1.ProcessLogMessageBuilder({
|
|
92
104
|
message: JSON.stringify({ type: "current-view", url }),
|
|
93
105
|
}));
|
|
94
|
-
await
|
|
106
|
+
await fs_extra_1.default.rmdir((process.cwd(), "gen-assets"), { recursive: true });
|
|
95
107
|
}
|
|
96
108
|
async sendMessage(message) {
|
|
97
109
|
const reporter = getReporter();
|
package/dist/uploader/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export declare const UPLOAD_BUCKET = "test-report";
|
|
2
2
|
export declare const UPLOAD_DOMAIN = "https://reports.empirical.run";
|
|
3
3
|
export declare function getFullUploadPath(filePath: string, uploadDir: string): string;
|
|
4
|
+
export declare function getRelativeUploadPath(filePath: string): string;
|
|
4
5
|
/**
|
|
5
6
|
* Function to upload test results to R2 using the project repo name and test name.
|
|
6
7
|
* This function uploads both the JSON summary of test results and associated video files.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/uploader/index.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,aAAa,gBAAgB,CAAC;AAC3C,eAAO,MAAM,aAAa,kCAAkC,CAAC;AAG7D,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/uploader/index.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,aAAa,gBAAgB,CAAC;AAC3C,eAAO,MAAM,aAAa,kCAAkC,CAAC;AAG7D,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,UAIpE;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,UAErD;AAED;;;;;;;;;GASG;AACH,wBAAsB,6BAA6B,CAAC,EAClD,eAAe,EACf,QAAQ,GACT,EAAE;IACD,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC;IACV,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC,CAwDD;AAED,wBAAgB,mBAAmB,CAAC,eAAe,EAAE,MAAM,UAM1D;AAED,wBAAgB,2BAA2B,uBAQ1C"}
|
package/dist/uploader/index.js
CHANGED
|
@@ -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.checkIfResultsUploadAllowed = exports.getUploadPathForRun = exports.uploadTestResultsUsingPrjRepo = exports.getFullUploadPath = exports.UPLOAD_DOMAIN = exports.UPLOAD_BUCKET = void 0;
|
|
6
|
+
exports.checkIfResultsUploadAllowed = exports.getUploadPathForRun = exports.uploadTestResultsUsingPrjRepo = exports.getRelativeUploadPath = exports.getFullUploadPath = exports.UPLOAD_DOMAIN = exports.UPLOAD_BUCKET = void 0;
|
|
7
7
|
const r2_uploader_1 = require("@empiricalrun/r2-uploader");
|
|
8
8
|
const reporter_1 = require("@empiricalrun/reporter");
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
@@ -18,13 +18,14 @@ exports.UPLOAD_DOMAIN = "https://reports.empirical.run"; // domain based on buck
|
|
|
18
18
|
const uploadId = crypto.randomUUID();
|
|
19
19
|
function getFullUploadPath(filePath, uploadDir) {
|
|
20
20
|
// remove the source dir from the file path - only keep the relative path
|
|
21
|
-
|
|
22
|
-
// new path for data: ~/source-repo/playwright-report/data/testName
|
|
23
|
-
const relativeFilePath = filePath.replace(path_1.default.join(process.cwd(), PLAYWRIGHT_REPORT_DATA), "");
|
|
24
|
-
// new relativeFilePath will look like
|
|
21
|
+
const relativeFilePath = getRelativeUploadPath(filePath);
|
|
25
22
|
return `${exports.UPLOAD_DOMAIN}/${uploadDir}${relativeFilePath}`;
|
|
26
23
|
}
|
|
27
24
|
exports.getFullUploadPath = getFullUploadPath;
|
|
25
|
+
function getRelativeUploadPath(filePath) {
|
|
26
|
+
return filePath.replace(path_1.default.join(process.cwd(), PLAYWRIGHT_REPORT_DATA), "");
|
|
27
|
+
}
|
|
28
|
+
exports.getRelativeUploadPath = getRelativeUploadPath;
|
|
28
29
|
/**
|
|
29
30
|
* Function to upload test results to R2 using the project repo name and test name.
|
|
30
31
|
* This function uploads both the JSON summary of test results and associated video files.
|
|
@@ -36,27 +37,21 @@ exports.getFullUploadPath = getFullUploadPath;
|
|
|
36
37
|
* @returns {string} returns.summaryUrl - URL of the uploaded summary JSON file.
|
|
37
38
|
*/
|
|
38
39
|
async function uploadTestResultsUsingPrjRepo({ projectRepoName, testName, }) {
|
|
39
|
-
// project repo name is the github repo name
|
|
40
|
-
// test-generation/<project-name>/<random-uuid>
|
|
41
40
|
const uploadDir = getUploadPathForRun(projectRepoName);
|
|
42
|
-
// upload test assets
|
|
43
41
|
const files = await (0, r2_uploader_1.uploadDirectory)({
|
|
44
|
-
|
|
45
|
-
sourceDir: path_1.default.join(process.cwd(), PLAYWRIGHT_REPORT_DATA), // upload data dir
|
|
42
|
+
sourceDir: path_1.default.join(process.cwd(), PLAYWRIGHT_REPORT_DATA),
|
|
46
43
|
destinationDir: uploadDir,
|
|
47
44
|
uploadBucket: exports.UPLOAD_BUCKET,
|
|
48
45
|
});
|
|
49
46
|
// upload summary.json
|
|
50
47
|
await (0, r2_uploader_1.uploadDirectory)({
|
|
51
|
-
|
|
52
|
-
sourceDir: path_1.default.join(process.cwd(), "playwright-report"), // upload data dir
|
|
48
|
+
sourceDir: path_1.default.join(process.cwd(), "playwright-report"),
|
|
53
49
|
fileList: [path_1.default.join(process.cwd(), "playwright-report", "summary.json")],
|
|
54
50
|
destinationDir: uploadDir,
|
|
55
51
|
uploadBucket: exports.UPLOAD_BUCKET,
|
|
56
52
|
});
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
// new default location: ..../source-repo/playwright-report/summary.json
|
|
53
|
+
// fileNames are relative upload paths
|
|
54
|
+
const fileNames = Object.keys(files);
|
|
60
55
|
const defaultLocation = path_1.default.join(process.cwd(), "playwright-report", "summary.json");
|
|
61
56
|
const results = (0, reporter_1.parseJsonReport)(defaultLocation);
|
|
62
57
|
const flatTestsList = (0, reporter_1.getFlattenedTestList)(results.suites);
|
|
@@ -68,24 +63,23 @@ async function uploadTestResultsUsingPrjRepo({ projectRepoName, testName, }) {
|
|
|
68
63
|
// results array is basically made by retries
|
|
69
64
|
for (const attachments of test.tests[0].results[0].attachments) {
|
|
70
65
|
if (attachments.path) {
|
|
71
|
-
testAttachmentPaths.push(attachments.path);
|
|
66
|
+
testAttachmentPaths.push(getRelativeUploadPath(attachments.path));
|
|
72
67
|
}
|
|
73
68
|
}
|
|
74
69
|
}
|
|
75
70
|
}
|
|
76
71
|
}
|
|
77
72
|
}
|
|
78
|
-
// current assumption
|
|
79
|
-
// - test gen will only run on a single spec file
|
|
80
|
-
// - the video files are of the format - <some-directory>/video.webm
|
|
81
73
|
const videoFiles = fileNames.filter((fileName) => fileName.endsWith(".webm") && testAttachmentPaths.includes(fileName));
|
|
82
74
|
const traceFiles = fileNames.filter((fileName) => fileName.endsWith(".zip") && testAttachmentPaths.includes(fileName));
|
|
83
75
|
return {
|
|
84
|
-
videoUrls: videoFiles
|
|
85
|
-
|
|
76
|
+
videoUrls: videoFiles
|
|
77
|
+
.map((fileName) => getFullUploadPath(fileName, uploadDir))
|
|
78
|
+
.filter((url) => !!url),
|
|
86
79
|
summaryUrl: `${exports.UPLOAD_DOMAIN}/${uploadDir}/summary.json`,
|
|
87
|
-
|
|
88
|
-
|
|
80
|
+
traceFiles: traceFiles
|
|
81
|
+
.map((fileName) => getFullUploadPath(fileName, uploadDir))
|
|
82
|
+
.filter((url) => !!url),
|
|
89
83
|
};
|
|
90
84
|
}
|
|
91
85
|
exports.uploadTestResultsUsingPrjRepo = uploadTestResultsUsingPrjRepo;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@empiricalrun/test-gen",
|
|
3
|
-
"version": "0.27.
|
|
3
|
+
"version": "0.27.8",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"registry": "https://registry.npmjs.org/",
|
|
6
6
|
"access": "public"
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
"ts-morph": "^23.0.0",
|
|
42
42
|
"tsx": "^4.16.2",
|
|
43
43
|
"typescript": "^5.3.3",
|
|
44
|
-
"@empiricalrun/llm": "^0.9.
|
|
45
|
-
"@empiricalrun/r2-uploader": "^0.
|
|
44
|
+
"@empiricalrun/llm": "^0.9.2",
|
|
45
|
+
"@empiricalrun/r2-uploader": "^0.2.0",
|
|
46
46
|
"@empiricalrun/reporter": "^0.18.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|