@empiricalrun/test-gen 0.43.1 → 0.43.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/dist/actions/skill.d.ts.map +1 -1
- package/dist/actions/skill.js +1 -0
- package/dist/agent/browsing/run.d.ts +3 -16
- package/dist/agent/browsing/run.d.ts.map +1 -1
- package/dist/agent/browsing/run.js +9 -10
- package/dist/agent/browsing/utils.d.ts +1 -1
- package/dist/agent/browsing/utils.d.ts.map +1 -1
- package/dist/agent/browsing/utils.js +3 -3
- package/dist/agent/master/action-tool-calls.d.ts.map +1 -1
- package/dist/agent/master/action-tool-calls.js +2 -1
- package/dist/agent/master/browser-tests/index.spec.js +1 -1
- package/dist/agent/master/next-action.d.ts.map +1 -1
- package/dist/agent/master/next-action.js +5 -2
- package/dist/agent/master/run.d.ts.map +1 -1
- package/dist/agent/master/run.js +5 -0
- package/dist/bin/index.js +29 -14
- package/dist/bin/utils/index.d.ts +7 -5
- package/dist/bin/utils/index.d.ts.map +1 -1
- package/dist/bin/utils/index.js +10 -26
- package/dist/bin/utils/platform/web/index.d.ts +1 -1
- package/dist/bin/utils/platform/web/index.d.ts.map +1 -1
- package/dist/bin/utils/platform/web/index.js +2 -2
- package/dist/bin/utils/scenarios/index.d.ts +3 -0
- package/dist/bin/utils/scenarios/index.d.ts.map +1 -1
- package/dist/bin/utils/scenarios/index.js +33 -1
- package/dist/browser-injected-scripts/annotate-elements.spec.js +22 -0
- package/dist/browser-injected-scripts/annotate-elements.spec.ts +32 -0
- package/dist/file/server.d.ts +4 -2
- package/dist/file/server.d.ts.map +1 -1
- package/dist/file/server.js +6 -4
- package/dist/initSentry.js +1 -1
- package/dist/reporter/index.d.ts +1 -0
- package/dist/reporter/index.d.ts.map +1 -1
- package/dist/reporter/index.js +13 -7
- package/dist/uploader/index.d.ts +4 -3
- package/dist/uploader/index.d.ts.map +1 -1
- package/dist/uploader/index.js +14 -14
- package/dist/utils/pw-test.d.ts +1 -1
- package/dist/utils/pw-test.d.ts.map +1 -1
- package/dist/utils/pw-test.js +5 -4
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @empiricalrun/test-gen
|
|
2
2
|
|
|
3
|
+
## 0.43.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 5334ba8: test: added failing test for multiple annotations for buttons
|
|
8
|
+
- 385d2c6: fix: disable sentry for local development environment
|
|
9
|
+
- 7b47902: chore: reduce assumptions of repo dir being process.cwd
|
|
10
|
+
- 1d0a746: feat: new cli args for --name, --file, and --prompt
|
|
11
|
+
- 0f342af: fix: break master agent loop if element is not visible after scroll
|
|
12
|
+
|
|
3
13
|
## 0.43.1
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../../src/actions/skill.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAGrD,eAAO,MAAM,WAAW,gBAAgB,CAAC;AAEzC,MAAM,MAAM,KAAK,GAAG;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,cAAM,cAAc;IACN,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,KAAK,EAAE;IAEnC,kBAAkB;IAIlB,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE;CAG7B;AAED,eAAO,MAAM,cAAc,gBAAyB,CAAC;AAErD,eAAO,MAAM,oBAAoB,EAAE,
|
|
1
|
+
{"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../../src/actions/skill.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAGrD,eAAO,MAAM,WAAW,gBAAgB,CAAC;AAEzC,MAAM,MAAM,KAAK,GAAG;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,cAAM,cAAc;IACN,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,KAAK,EAAE;IAEnC,kBAAkB;IAIlB,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE;CAG7B;AAED,eAAO,MAAM,cAAc,gBAAyB,CAAC;AAErD,eAAO,MAAM,oBAAoB,EAAE,yBAoHlC,CAAC"}
|
package/dist/actions/skill.js
CHANGED
|
@@ -33,6 +33,7 @@ const skillActionGenerator = (page, options) => {
|
|
|
33
33
|
throw new Error(`No skill found for skill: ${skill}`);
|
|
34
34
|
}
|
|
35
35
|
const skillFilePath = skillDetails.filePath;
|
|
36
|
+
// This assumes repoDir is process.cwd()
|
|
36
37
|
const [lastDir] = process.cwd().split("/").reverse();
|
|
37
38
|
const dir = `${process.cwd()}/${lastDir}`;
|
|
38
39
|
const module = await api_1.default.require(`./${skillFilePath}`, dir);
|
|
@@ -1,22 +1,9 @@
|
|
|
1
1
|
type GenerateTestsType = {
|
|
2
|
-
/**
|
|
3
|
-
* Path to the test case file being updated or created
|
|
4
|
-
*
|
|
5
|
-
* @type {string}
|
|
6
|
-
*/
|
|
7
2
|
testFilePath: string;
|
|
8
|
-
/**
|
|
9
|
-
* File path being updated for the concerned test case
|
|
10
|
-
*
|
|
11
|
-
* @type {string}
|
|
12
|
-
*/
|
|
13
3
|
filePathToUpdate: string;
|
|
14
|
-
/**
|
|
15
|
-
* playwright projects to filter
|
|
16
|
-
*
|
|
17
|
-
* @type {string[]}
|
|
18
|
-
*/
|
|
19
4
|
pwProjectsFilter: string[];
|
|
5
|
+
testGenToken: string;
|
|
6
|
+
repoDir: string;
|
|
20
7
|
};
|
|
21
8
|
/**
|
|
22
9
|
*
|
|
@@ -27,6 +14,6 @@ type GenerateTestsType = {
|
|
|
27
14
|
* filePathToUpdate,
|
|
28
15
|
* }
|
|
29
16
|
*/
|
|
30
|
-
export declare function generateTestsUsingMasterAgent({ testFilePath, filePathToUpdate, pwProjectsFilter, }: GenerateTestsType): Promise<void>;
|
|
17
|
+
export declare function generateTestsUsingMasterAgent({ testFilePath, filePathToUpdate, pwProjectsFilter, testGenToken, repoDir, }: GenerateTestsType): Promise<void>;
|
|
31
18
|
export {};
|
|
32
19
|
//# sourceMappingURL=run.d.ts.map
|
|
@@ -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":"AAmBA,KAAK,iBAAiB,GAAG;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAsB,6BAA6B,CAAC,EAClD,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,OAAO,GACR,EAAE,iBAAiB,iBA8EnB"}
|
|
@@ -30,11 +30,10 @@ exports.generateTestsUsingMasterAgent = void 0;
|
|
|
30
30
|
const Sentry = __importStar(require("@sentry/node"));
|
|
31
31
|
const detect_port_1 = __importDefault(require("detect-port"));
|
|
32
32
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
33
|
-
const utils_1 = require("../../bin/utils");
|
|
34
33
|
const web_1 = require("../../bin/utils/platform/web");
|
|
35
34
|
const server_1 = require("../../file/server");
|
|
36
35
|
const exec_1 = require("../../utils/exec");
|
|
37
|
-
const
|
|
36
|
+
const utils_1 = require("./utils");
|
|
38
37
|
/**
|
|
39
38
|
*
|
|
40
39
|
* Function to generate tests using master agent
|
|
@@ -44,28 +43,28 @@ const utils_2 = require("./utils");
|
|
|
44
43
|
* filePathToUpdate,
|
|
45
44
|
* }
|
|
46
45
|
*/
|
|
47
|
-
async function generateTestsUsingMasterAgent({ testFilePath, filePathToUpdate, pwProjectsFilter, }) {
|
|
46
|
+
async function generateTestsUsingMasterAgent({ testFilePath, filePathToUpdate, pwProjectsFilter, testGenToken, repoDir, }) {
|
|
48
47
|
// valiate if the file path and file to update are valid
|
|
49
48
|
// also warn users if they are on older version of test-gen
|
|
50
|
-
(0,
|
|
49
|
+
(0, utils_1.canRunMasterAgent)(testFilePath);
|
|
51
50
|
// detect available http port on the machine
|
|
52
51
|
const port = await (0, detect_port_1.default)(3030);
|
|
53
52
|
// start a file service to handle file updates from agent
|
|
54
53
|
// - also update the file path with updates when agent is done spitting out code
|
|
55
|
-
const fileService = new server_1.FileService({ port });
|
|
54
|
+
const fileService = new server_1.FileService({ port, repoDir });
|
|
56
55
|
await fileService.startFileService();
|
|
57
56
|
fileService.setFilePath(filePathToUpdate);
|
|
58
57
|
// read playwright config from ./playwright.config.ts of source repo
|
|
59
|
-
const playwrightConfig = await (0,
|
|
58
|
+
const playwrightConfig = await (0, utils_1.readPlaywrightConfig)(repoDir);
|
|
60
59
|
// detect the playwright project name for the given test file and playwright config
|
|
61
|
-
const project = await (0,
|
|
60
|
+
const project = await (0, utils_1.detectProjectName)(testFilePath, playwrightConfig, pwProjectsFilter);
|
|
62
61
|
const pageVar = await (0, web_1.getPageVariableNameFromCreateTest)(filePathToUpdate);
|
|
63
62
|
console.log(`Detected playwright project name: ${project}`);
|
|
64
63
|
// run playwright test which will internally run the master agent
|
|
65
64
|
const teardownFileRegex = /.*\.teardown\.ts/;
|
|
66
|
-
const testsDirectory = `${
|
|
65
|
+
const testsDirectory = `${repoDir}/tests`;
|
|
67
66
|
const isTestRunTriggeredForTeardown = teardownFileRegex.test(testFilePath);
|
|
68
|
-
const teardowns = new
|
|
67
|
+
const teardowns = new utils_1.TeardownManager(testsDirectory);
|
|
69
68
|
if (!isTestRunTriggeredForTeardown) {
|
|
70
69
|
await teardowns.skipAll();
|
|
71
70
|
}
|
|
@@ -77,7 +76,7 @@ async function generateTestsUsingMasterAgent({ testFilePath, filePathToUpdate, p
|
|
|
77
76
|
APP_PORT: port.toString(),
|
|
78
77
|
PW_TEST_HTML_REPORT_OPEN: "never",
|
|
79
78
|
// pass the test gen token so that the agent has the same configuration as cli
|
|
80
|
-
TEST_GEN_TOKEN:
|
|
79
|
+
TEST_GEN_TOKEN: testGenToken,
|
|
81
80
|
PAGE_VAR_NAME: pageVar || "page",
|
|
82
81
|
DISPLAY: ":99",
|
|
83
82
|
},
|
|
@@ -21,7 +21,7 @@ export declare function canRunMasterAgent(filePath: string): void;
|
|
|
21
21
|
* function to read playwright config from the source repo
|
|
22
22
|
* @return {*} {Promise<PlaywrightTestConfig>}
|
|
23
23
|
*/
|
|
24
|
-
export declare function readPlaywrightConfig(): Promise<PlaywrightTestConfig>;
|
|
24
|
+
export declare function readPlaywrightConfig(repoDir: string): Promise<PlaywrightTestConfig>;
|
|
25
25
|
/**
|
|
26
26
|
* detect the project name for the given file in playwright test repo
|
|
27
27
|
* if project and test file path for running test don't match, then playwright throws error
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAe,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAI7E,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAsBvD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,MAAM,CAKhD;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,UAIvD;AA8FD;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,aAAa,EACxB,KAAK,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC,MAAM,CAAC,CA0DjB;AAyBD,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,IAAI,iBA2HxD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,QAIjD;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAe,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAI7E,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAsBvD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,MAAM,CAKhD;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,UAIvD;AA8FD;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,aAAa,EACxB,KAAK,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC,MAAM,CAAC,CA0DjB;AAyBD,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,IAAI,iBA2HxD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,QAIjD;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,oBAAoB,CAAC,CAM/B;AAWD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,oBAAoB,EACtC,gBAAgB,GAAE,MAAM,EAAU,GACjC,OAAO,CAAC,MAAM,CAAC,CA+CjB;AAED,qBAAa,eAAe;IACd,OAAO,CAAC,SAAS;gBAAT,SAAS,EAAE,MAAM;IACrC,OAAO,CAAC,aAAa,CAAqB;YAE5B,mBAAmB;YAUnB,gBAAgB;IAsBjB,OAAO;IAuBb,SAAS;CAKjB"}
|
|
@@ -286,9 +286,9 @@ exports.canRunMasterAgent = canRunMasterAgent;
|
|
|
286
286
|
* function to read playwright config from the source repo
|
|
287
287
|
* @return {*} {Promise<PlaywrightTestConfig>}
|
|
288
288
|
*/
|
|
289
|
-
async function readPlaywrightConfig() {
|
|
290
|
-
const [lastDir] =
|
|
291
|
-
const playwrightConfig = (await api_1.default.require("./playwright.config.ts", `${
|
|
289
|
+
async function readPlaywrightConfig(repoDir) {
|
|
290
|
+
const [lastDir] = repoDir.split("/").reverse();
|
|
291
|
+
const playwrightConfig = (await api_1.default.require("./playwright.config.ts", `${repoDir}/${lastDir}`)).default;
|
|
292
292
|
return playwrightConfig;
|
|
293
293
|
}
|
|
294
294
|
exports.readPlaywrightConfig = readPlaywrightConfig;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action-tool-calls.d.ts","sourceRoot":"","sources":["../../../src/agent/master/action-tool-calls.ts"],"names":[],"mappings":"AAAA,oBAAY,UAAU;IACpB,IAAI,SAAS;IACb,SAAS,cAAc;IACvB,KAAK,UAAU;IACf,YAAY,8BAA8B;IAC1C,WAAW,gBAAgB;IAC3B,KAAK,kBAAkB;IACvB,MAAM,WAAW;CAClB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,UAAU,
|
|
1
|
+
{"version":3,"file":"action-tool-calls.d.ts","sourceRoot":"","sources":["../../../src/agent/master/action-tool-calls.ts"],"names":[],"mappings":"AAAA,oBAAY,UAAU;IACpB,IAAI,SAAS;IACb,SAAS,cAAc;IACvB,KAAK,UAAU;IACf,YAAY,8BAA8B;IAC1C,WAAW,gBAAgB;IAC3B,KAAK,kBAAkB;IACvB,MAAM,WAAW;CAClB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,UAAU,CAKpE;AAyDD,wBAAgB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAoCjC"}
|
|
@@ -12,7 +12,8 @@ var ActionType;
|
|
|
12
12
|
ActionType["SCROLL"] = "scroll";
|
|
13
13
|
})(ActionType || (exports.ActionType = ActionType = {}));
|
|
14
14
|
function isValidActionType(value) {
|
|
15
|
-
return Object.values(ActionType).includes(value)
|
|
15
|
+
return (Object.values(ActionType).includes(value) ||
|
|
16
|
+
value === "unknown");
|
|
16
17
|
}
|
|
17
18
|
exports.isValidActionType = isValidActionType;
|
|
18
19
|
const createActionCall = (name, description, additionalProperties = {}) => ({
|
|
@@ -38,7 +38,7 @@ test_1.test.afterAll(() => {
|
|
|
38
38
|
(0, test_1.expect)(response.code).toContain("await page.getByPlaceholder('Enter your email').fill(\"test@test.com\")");
|
|
39
39
|
(0, test_1.expect)(response.code).toContain("await page.getByRole('button', { name: 'Subscribe' }).click()");
|
|
40
40
|
});
|
|
41
|
-
test_1.test
|
|
41
|
+
(0, test_1.test)("scroll when element does not exist", async ({ page }) => {
|
|
42
42
|
await page.goto(`http://localhost:${PORT}/blog-page.html`);
|
|
43
43
|
const response = await (0, run_1.createTestUsingMasterAgent)({
|
|
44
44
|
task: `click search button`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"next-action.d.ts","sourceRoot":"","sources":["../../../src/agent/master/next-action.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAMhD,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAAE,UAAU,EAAsB,MAAM,qBAAqB,CAAC;AAGrE,wBAAsB,aAAa,CAAC,EAClC,IAAI,EACJ,eAAe,EACf,aAAa,EACb,OAAO,EACP,KAAK,EACL,GAAG,EACH,OAAO,EACP,cAAc,EACd,OAAO,EACP,WAAW,EACX,aAAa,EACb,IAAI,EACJ,MAAM,GACP,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,EAAE,GAAG,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,WAAW,EAAE,OAAO,UAAU,CAAC;IAC/B,aAAa,EAAE,OAAO,CAAC;IACvB,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB,GAAG,OAAO,CACP;IACE,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB,GACD,SAAS,CACZ,
|
|
1
|
+
{"version":3,"file":"next-action.d.ts","sourceRoot":"","sources":["../../../src/agent/master/next-action.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAMhD,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAAE,UAAU,EAAsB,MAAM,qBAAqB,CAAC;AAGrE,wBAAsB,aAAa,CAAC,EAClC,IAAI,EACJ,eAAe,EACf,aAAa,EACb,OAAO,EACP,KAAK,EACL,GAAG,EACH,OAAO,EACP,cAAc,EACd,OAAO,EACP,WAAW,EACX,aAAa,EACb,IAAI,EACJ,MAAM,GACP,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,EAAE,GAAG,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,WAAW,EAAE,OAAO,UAAU,CAAC;IAC/B,aAAa,EAAE,OAAO,CAAC;IACvB,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB,GAAG,OAAO,CACP;IACE,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB,GACD,SAAS,CACZ,CAuLA"}
|
|
@@ -167,8 +167,11 @@ async function getNextAction({ task, executedActions, failedActions, pageUrl, tr
|
|
|
167
167
|
});
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
|
-
if (maxScrollRetries ===
|
|
171
|
-
|
|
170
|
+
if (maxScrollRetries === -1) {
|
|
171
|
+
return {
|
|
172
|
+
actionType: "unknown",
|
|
173
|
+
toolCallArgs: "",
|
|
174
|
+
};
|
|
172
175
|
}
|
|
173
176
|
}
|
|
174
177
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/master/run.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAclC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EACL,oBAAoB,EAErB,MAAM,aAAa,CAAC;AA6BrB,wBAAsB,0BAA0B,CAAC,EAC/C,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,SAAS,GACV,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,oBAAoB,CAAC;IAC9B,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;;;
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/master/run.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAclC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EACL,oBAAoB,EAErB,MAAM,aAAa,CAAC;AA6BrB,wBAAsB,0BAA0B,CAAC,EAC/C,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,SAAS,GACV,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,oBAAoB,CAAC;IAC9B,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;;;GA+WA"}
|
package/dist/agent/master/run.js
CHANGED
|
@@ -159,6 +159,11 @@ async function createTestUsingMasterAgent({ task, page, testCase, specPath, opti
|
|
|
159
159
|
break;
|
|
160
160
|
}
|
|
161
161
|
if (toolCall) {
|
|
162
|
+
if (toolCall.actionType === "unknown") {
|
|
163
|
+
logger.error("Agent is not able to figure out next action since element is not visible on screen.");
|
|
164
|
+
await testgenUpdatesReporter.sendMessage("Agent is not able to figure out next action since element is not visible on screen.");
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
162
167
|
const args = (0, utils_3.parseJson)(toolCall.toolCallArgs);
|
|
163
168
|
const masterAgentActionSpan = masterAgentSpan?.span({
|
|
164
169
|
name: "master-agent-execute-action",
|
package/dist/bin/index.js
CHANGED
|
@@ -30,6 +30,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
30
30
|
require("../initSentry");
|
|
31
31
|
const llm_1 = require("@empiricalrun/llm");
|
|
32
32
|
const Sentry = __importStar(require("@sentry/node"));
|
|
33
|
+
const commander_1 = require("commander");
|
|
33
34
|
const dotenv_1 = __importDefault(require("dotenv"));
|
|
34
35
|
const run_1 = require("../agent/browsing/run");
|
|
35
36
|
const utils_1 = require("../agent/browsing/utils");
|
|
@@ -44,6 +45,7 @@ const session_1 = require("../session");
|
|
|
44
45
|
const test_build_1 = require("../test-build");
|
|
45
46
|
const logger_1 = require("./logger");
|
|
46
47
|
const utils_2 = require("./utils");
|
|
48
|
+
const scenarios_1 = require("./utils/scenarios");
|
|
47
49
|
dotenv_1.default.config({
|
|
48
50
|
path: [".env.local", ".env"],
|
|
49
51
|
});
|
|
@@ -62,7 +64,7 @@ async function resolveAgentUsingTask({ testCase, trace, }) {
|
|
|
62
64
|
});
|
|
63
65
|
return response;
|
|
64
66
|
}
|
|
65
|
-
async function runAgent(testGenConfig, span) {
|
|
67
|
+
async function runAgent(testGenConfig, testGenToken, span) {
|
|
66
68
|
const logger = new logger_1.CustomLogger();
|
|
67
69
|
const { specPath, testCase } = testGenConfig;
|
|
68
70
|
if (process.env.LOG_URL) {
|
|
@@ -87,7 +89,8 @@ async function runAgent(testGenConfig, span) {
|
|
|
87
89
|
if (await (0, session_1.shouldStopSession)()) {
|
|
88
90
|
return;
|
|
89
91
|
}
|
|
90
|
-
let
|
|
92
|
+
let agentFromConfig = testGenConfig.options?.agent;
|
|
93
|
+
let agent = agentFromConfig || "auto";
|
|
91
94
|
trace?.update({
|
|
92
95
|
metadata: {
|
|
93
96
|
generationId: session.generationId,
|
|
@@ -132,9 +135,8 @@ async function runAgent(testGenConfig, span) {
|
|
|
132
135
|
testCase,
|
|
133
136
|
trace,
|
|
134
137
|
});
|
|
135
|
-
testGenConfig.options.agent = agent;
|
|
136
138
|
}
|
|
137
|
-
logger.success(`Generating test using ${
|
|
139
|
+
logger.success(`Generating test using ${agent} agent. ${process.env.LOG_URL ? `[view log](${process.env.LOG_URL})` : ""}`);
|
|
138
140
|
if (testGenConfig.testErrorDiagnosis &&
|
|
139
141
|
testGenConfig.testErrorDiagnosis.failingLine) {
|
|
140
142
|
const requestedChangeResp = await (0, enrich_prompt_1.enrichPromptWithFailingLine)({
|
|
@@ -168,19 +170,30 @@ async function runAgent(testGenConfig, span) {
|
|
|
168
170
|
testFilePath: specPath,
|
|
169
171
|
filePathToUpdate,
|
|
170
172
|
pwProjectsFilter: testGenConfig.environment?.playwrightProjects,
|
|
173
|
+
testGenToken,
|
|
174
|
+
repoDir: process.cwd(),
|
|
171
175
|
});
|
|
172
176
|
}
|
|
177
|
+
return agent;
|
|
173
178
|
}
|
|
174
179
|
(async function main() {
|
|
175
180
|
await Sentry.continueTrace({ sentryTrace: utils_2.sentryTrace, baggage: utils_2.baggage }, async () => {
|
|
176
181
|
await Sentry.startSpan({ name: "test-gen" }, async (span) => {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
182
|
+
const program = new commander_1.Command();
|
|
183
|
+
program
|
|
184
|
+
.option("--token <token>", "Test generation token")
|
|
185
|
+
.option("--name <test-name>", "Name of the test case")
|
|
186
|
+
.option("--prompt <prompt>", "Prompt for the test case")
|
|
187
|
+
.option("--file <test-file>", "File path of the test case (inside tests dir)")
|
|
188
|
+
.parse(process.argv);
|
|
189
|
+
const options = program.opts();
|
|
190
|
+
(0, utils_2.validateCliOptions)(options);
|
|
191
|
+
const testGenConfig = options.token
|
|
192
|
+
? (0, scenarios_1.loadTestConfigs)(options.token)
|
|
193
|
+
: (0, scenarios_1.buildTestConfigFromOptions)(options);
|
|
194
|
+
const testGenToken = options.token
|
|
195
|
+
? options.token
|
|
196
|
+
: (0, scenarios_1.buildTokenFromOptions)(options);
|
|
184
197
|
(0, reporter_1.setReporterConfig)({
|
|
185
198
|
projectRepoName: testGenConfig.options?.metadata.projectRepoName,
|
|
186
199
|
testSessionId: testGenConfig.options?.metadata.testSessionId,
|
|
@@ -193,10 +206,11 @@ async function runAgent(testGenConfig, span) {
|
|
|
193
206
|
projectRepoName: testGenConfig.options?.metadata.projectRepoName,
|
|
194
207
|
});
|
|
195
208
|
let testGenFailed = false;
|
|
209
|
+
let agentUsed;
|
|
196
210
|
try {
|
|
197
211
|
// download the build if it exists
|
|
198
212
|
await (0, test_build_1.downloadBuild)(testGenConfig.build || {});
|
|
199
|
-
await runAgent(testGenConfig);
|
|
213
|
+
agentUsed = await runAgent(testGenConfig, testGenToken);
|
|
200
214
|
}
|
|
201
215
|
catch (e) {
|
|
202
216
|
span.recordException(e);
|
|
@@ -204,8 +218,9 @@ async function runAgent(testGenConfig, span) {
|
|
|
204
218
|
testGenFailed = true;
|
|
205
219
|
new logger_1.CustomLogger().error(`Failed to generate test for the scenario. ${process.env.LOG_URL ? `[view log](${process.env.LOG_URL})` : ""}`, e?.message, e?.stack);
|
|
206
220
|
}
|
|
207
|
-
if (
|
|
208
|
-
|
|
221
|
+
if (agentUsed &&
|
|
222
|
+
agentUsed !== "code" &&
|
|
223
|
+
agentUsed !== "plan" &&
|
|
209
224
|
testGenConfig.testCase.name) {
|
|
210
225
|
await new reporter_1.TestGenUpdatesReporter().reportGenAssets({
|
|
211
226
|
projectRepoName: testGenConfig.options.metadata.projectRepoName,
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import type { TestGenConfig } from "@empiricalrun/shared-types";
|
|
2
|
-
export declare function parseCliArgs(): Promise<{
|
|
3
|
-
testGenConfig: TestGenConfig;
|
|
4
|
-
}>;
|
|
5
|
-
export declare function getTestConfigCliArg(): string;
|
|
6
1
|
export declare const sentryTrace: string | undefined;
|
|
7
2
|
export declare const baggage: string | undefined;
|
|
3
|
+
export interface CliOptions {
|
|
4
|
+
token?: string;
|
|
5
|
+
name?: string;
|
|
6
|
+
file?: string;
|
|
7
|
+
prompt?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function validateCliOptions(options: CliOptions): void;
|
|
8
10
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bin/utils/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bin/utils/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,oBAA2B,CAAC;AACpD,eAAO,MAAM,OAAO,oBAA6B,CAAC;AAElD,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAS5D"}
|
package/dist/bin/utils/index.js
CHANGED
|
@@ -1,30 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const logger_1 = require("../logger");
|
|
5
|
-
const scenarios_1 = require("./scenarios");
|
|
6
|
-
async function parseCliArgs() {
|
|
7
|
-
let rawToken = getTestConfigCliArg();
|
|
8
|
-
const testGenConfig = (0, scenarios_1.loadTestConfigs)(rawToken);
|
|
9
|
-
return {
|
|
10
|
-
testGenConfig,
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
exports.parseCliArgs = parseCliArgs;
|
|
14
|
-
function getTestConfigCliArg() {
|
|
15
|
-
// Check for --token parameter
|
|
16
|
-
const tokenIndex = process.argv.indexOf("--token");
|
|
17
|
-
if (tokenIndex !== -1 && process.argv[tokenIndex + 1]) {
|
|
18
|
-
const token = process.argv[tokenIndex + 1];
|
|
19
|
-
if (token)
|
|
20
|
-
return token;
|
|
21
|
-
}
|
|
22
|
-
// Fallback to legacy behavior (token as first argument)
|
|
23
|
-
const legacyToken = process.argv[2];
|
|
24
|
-
const logger = new logger_1.CustomLogger({ useReporter: false });
|
|
25
|
-
logger.warn("Using legacy token format. Consider using --token parameter instead: npx @empiricalrun/test-gen --token <TEST_GEN_TOKEN>");
|
|
26
|
-
return legacyToken;
|
|
27
|
-
}
|
|
28
|
-
exports.getTestConfigCliArg = getTestConfigCliArg;
|
|
3
|
+
exports.validateCliOptions = exports.baggage = exports.sentryTrace = void 0;
|
|
29
4
|
exports.sentryTrace = process.env.SENTRY_TRACE;
|
|
30
5
|
exports.baggage = process.env.SENTRY_BAGGAGE;
|
|
6
|
+
function validateCliOptions(options) {
|
|
7
|
+
const hasToken = !!options.token;
|
|
8
|
+
const hasNameAndFile = !!options.name && !!options.file && !!options.prompt;
|
|
9
|
+
if (!hasToken && !hasNameAndFile) {
|
|
10
|
+
console.error("Invalid arguments. Provide either --token OR all of --name, --file, and --prompt");
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.validateCliOptions = validateCliOptions;
|
|
@@ -58,7 +58,7 @@ export declare const injectCodeSnippetBySuiteChain: ({ testFileContent, codeSnip
|
|
|
58
58
|
codeSnippet: string;
|
|
59
59
|
suites: string[];
|
|
60
60
|
}) => string;
|
|
61
|
-
export declare const importAllExportsStmtFromFilePaths: (filePaths: string[], testFilePath: string) => Promise<string[]>;
|
|
61
|
+
export declare const importAllExportsStmtFromFilePaths: (repoDir: string, filePaths: string[], testFilePath: string) => Promise<string[]>;
|
|
62
62
|
export declare function addUserContextFixture({ scenarioName, filePath, suites, }: {
|
|
63
63
|
scenarioName: string;
|
|
64
64
|
filePath: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/bin/utils/platform/web/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAM3D,OAAO,EAGL,IAAI,EAEJ,UAAU,EAEX,MAAM,UAAU,CAAC;AAGlB,eAAO,MAAM,gCAAgC,eAC/B,UAAU,KACrB,MAgBF,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,YAAY,EACZ,MAAM,EACN,OAAO,GACR,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG;IACF,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,QAAQ,EAAE,IAAI,GAAG,SAAS,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;CACnB,CA2CA;AAwBD,wBAAsB,0CAA0C,CAC9D,QAAQ,EAAE,MAAM,oBA+BjB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,IAAI,GAAG,SAAS,GACrB,IAAI,GAAG,SAAS,CA4BlB;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAG5E;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CA8C7D;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,mCAWjB;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,iBAShD;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,iBAgBrE;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,UAE5E;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,iBAMpD;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,UAcpD;AAED,wBAAsB,iCAAiC,CAAC,QAAQ,EAAE,MAAM,+BAoBvE;AA+CD,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,UAoCtB;AAED,eAAO,MAAM,6BAA6B;qBAKvB,MAAM;iBACV,MAAM;YACX,MAAM,EAAE;YA2DjB,CAAC;AAEF,eAAO,MAAM,iCAAiC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/bin/utils/platform/web/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAM3D,OAAO,EAGL,IAAI,EAEJ,UAAU,EAEX,MAAM,UAAU,CAAC;AAGlB,eAAO,MAAM,gCAAgC,eAC/B,UAAU,KACrB,MAgBF,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,YAAY,EACZ,MAAM,EACN,OAAO,GACR,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG;IACF,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,QAAQ,EAAE,IAAI,GAAG,SAAS,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;CACnB,CA2CA;AAwBD,wBAAsB,0CAA0C,CAC9D,QAAQ,EAAE,MAAM,oBA+BjB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,IAAI,GAAG,SAAS,GACrB,IAAI,GAAG,SAAS,CA4BlB;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAG5E;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CA8C7D;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,mCAWjB;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,iBAShD;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,iBAgBrE;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,UAE5E;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,iBAMpD;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,UAcpD;AAED,wBAAsB,iCAAiC,CAAC,QAAQ,EAAE,MAAM,+BAoBvE;AA+CD,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,UAoCtB;AAED,eAAO,MAAM,6BAA6B;qBAKvB,MAAM;iBACV,MAAM;YACX,MAAM,EAAE;YA2DjB,CAAC;AAEF,eAAO,MAAM,iCAAiC,YACnC,MAAM,aACJ,MAAM,EAAE,gBACL,MAAM,sBAyBrB,CAAC;AAEF,wBAAsB,qBAAqB,CAAC,EAC1C,YAAY,EACZ,QAAQ,EACR,MAAM,GACP,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,iBAgDA;AAED,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EAAE,iBAsBzB;AAED,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;CACpB,WAYA;AAED,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,MAAM,GACP,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,UAOA;AAED,wBAAgB,+BAA+B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CA4B5E;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQnD"}
|
|
@@ -398,10 +398,10 @@ const injectCodeSnippetBySuiteChain = ({ testFileContent, codeSnippet, suites, }
|
|
|
398
398
|
return sourceFile.getFullText();
|
|
399
399
|
};
|
|
400
400
|
exports.injectCodeSnippetBySuiteChain = injectCodeSnippetBySuiteChain;
|
|
401
|
-
const importAllExportsStmtFromFilePaths = async (filePaths, testFilePath) => {
|
|
401
|
+
const importAllExportsStmtFromFilePaths = async (repoDir, filePaths, testFilePath) => {
|
|
402
402
|
const statements = [];
|
|
403
403
|
for (const filePath of filePaths) {
|
|
404
|
-
const fullPath = path_1.default.resolve(
|
|
404
|
+
const fullPath = path_1.default.resolve(repoDir, filePath);
|
|
405
405
|
let importPath = path_1.default.relative(path_1.default.dirname(testFilePath), filePath);
|
|
406
406
|
if (!importPath.startsWith(".")) {
|
|
407
407
|
importPath = "./" + importPath;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import type { TestGenConfig } from "@empiricalrun/shared-types";
|
|
2
|
+
import { CliOptions } from "../index";
|
|
3
|
+
export declare function buildTokenFromOptions(options: Omit<CliOptions, "token">): string;
|
|
4
|
+
export declare function buildTestConfigFromOptions(options: Omit<CliOptions, "token">): TestGenConfig;
|
|
2
5
|
export declare function loadTestConfigs(testGenToken: string): TestGenConfig;
|
|
3
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/bin/utils/scenarios/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,aAAa,EAEd,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/bin/utils/scenarios/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,aAAa,EAEd,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAetC,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,GACjC,MAAM,CAgBR;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,GACjC,aAAa,CAYf;AAED,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,aAAa,CAmBnE"}
|
|
@@ -1,6 +1,38 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.loadTestConfigs = void 0;
|
|
3
|
+
exports.loadTestConfigs = exports.buildTestConfigFromOptions = exports.buildTokenFromOptions = void 0;
|
|
4
|
+
function buildTokenFromOptions(options) {
|
|
5
|
+
const genConfig = buildTestConfigFromOptions(options);
|
|
6
|
+
const requestConfig = {
|
|
7
|
+
specPath: genConfig.specPath,
|
|
8
|
+
id: genConfig.testCase.id,
|
|
9
|
+
name: genConfig.testCase.name,
|
|
10
|
+
steps: genConfig.testCase.steps,
|
|
11
|
+
filePath: genConfig.testCase.filePath,
|
|
12
|
+
suites: genConfig.testCase.suites,
|
|
13
|
+
ai_gist: genConfig.testCase.ai_gist,
|
|
14
|
+
build: genConfig.build,
|
|
15
|
+
options: genConfig.options,
|
|
16
|
+
environment: genConfig.environment,
|
|
17
|
+
testErrorDiagnosis: genConfig.testErrorDiagnosis,
|
|
18
|
+
};
|
|
19
|
+
return btoa(encodeURIComponent(JSON.stringify(requestConfig)));
|
|
20
|
+
}
|
|
21
|
+
exports.buildTokenFromOptions = buildTokenFromOptions;
|
|
22
|
+
function buildTestConfigFromOptions(options) {
|
|
23
|
+
return {
|
|
24
|
+
specPath: `./tests/${options.file}`,
|
|
25
|
+
testCase: {
|
|
26
|
+
id: 0,
|
|
27
|
+
name: options.name,
|
|
28
|
+
steps: [options.prompt],
|
|
29
|
+
filePath: options.file,
|
|
30
|
+
// TODO: Support suites in this flow
|
|
31
|
+
suites: [],
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
exports.buildTestConfigFromOptions = buildTestConfigFromOptions;
|
|
4
36
|
function loadTestConfigs(testGenToken) {
|
|
5
37
|
const str = decodeURIComponent(atob(testGenToken));
|
|
6
38
|
const config = JSON.parse(str);
|
|
@@ -183,3 +183,25 @@ const action_tool_calls_1 = require("../agent/master/action-tool-calls");
|
|
|
183
183
|
test_1.test.expect(annotations.length).toBe(1);
|
|
184
184
|
test_1.test.expect(annotations[0]?.tagName).toBe("DIV");
|
|
185
185
|
});
|
|
186
|
+
test_1.test.fail("should not annotate children that don't have onClick handler", async ({ page }) => {
|
|
187
|
+
await page.setContent(`<div class="button-outer" onclick="alert('clicked')">
|
|
188
|
+
<div class="button-inner">Click me</div>
|
|
189
|
+
</div>`);
|
|
190
|
+
await page.addScriptTag({
|
|
191
|
+
path: path_1.default.resolve(__dirname, "./annotate-elements.js"),
|
|
192
|
+
});
|
|
193
|
+
const annotations = await page.evaluate(() => {
|
|
194
|
+
// eslint-disable-next-line no-undef
|
|
195
|
+
const { annotations } = annotateElementsWithPreference();
|
|
196
|
+
return Object.entries(annotations).map(([hint, config]) => ({
|
|
197
|
+
hint,
|
|
198
|
+
innerText: config.node.innerText?.toLowerCase().trim(),
|
|
199
|
+
tagName: config.node.tagName,
|
|
200
|
+
testId: config.node.getAttribute("data-testid"),
|
|
201
|
+
className: config.node.className,
|
|
202
|
+
}));
|
|
203
|
+
});
|
|
204
|
+
console.log(annotations);
|
|
205
|
+
test_1.test.expect(annotations.length).toBe(1);
|
|
206
|
+
test_1.test.expect(annotations[0].className).toBe("button-outer");
|
|
207
|
+
});
|
|
@@ -299,3 +299,35 @@ test("should only annotate given text on quizziz page", async ({ page }) => {
|
|
|
299
299
|
test.expect(annotations.length).toBe(1);
|
|
300
300
|
test.expect(annotations[0]?.tagName).toBe("DIV");
|
|
301
301
|
});
|
|
302
|
+
|
|
303
|
+
test.fail(
|
|
304
|
+
"should not annotate children that don't have onClick handler",
|
|
305
|
+
async ({ page }) => {
|
|
306
|
+
await page.setContent(
|
|
307
|
+
`<div class="button-outer" onclick="alert('clicked')">
|
|
308
|
+
<div class="button-inner">Click me</div>
|
|
309
|
+
</div>`,
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
await page.addScriptTag({
|
|
313
|
+
path: path.resolve(__dirname, "./annotate-elements.js"),
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
const annotations = await page.evaluate(() => {
|
|
317
|
+
// eslint-disable-next-line no-undef
|
|
318
|
+
const { annotations } = annotateElementsWithPreference();
|
|
319
|
+
|
|
320
|
+
return Object.entries(annotations).map(([hint, config]) => ({
|
|
321
|
+
hint,
|
|
322
|
+
innerText: config.node.innerText?.toLowerCase().trim(),
|
|
323
|
+
tagName: config.node.tagName,
|
|
324
|
+
testId: config.node.getAttribute("data-testid"),
|
|
325
|
+
className: config.node.className,
|
|
326
|
+
}));
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
console.log(annotations);
|
|
330
|
+
test.expect(annotations.length).toBe(1);
|
|
331
|
+
test.expect(annotations[0].className).toBe("button-outer");
|
|
332
|
+
},
|
|
333
|
+
);
|
package/dist/file/server.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
export declare class FileService {
|
|
2
|
-
private filePath;
|
|
3
2
|
private port;
|
|
4
|
-
|
|
3
|
+
private filePath;
|
|
4
|
+
private repoDir;
|
|
5
|
+
constructor({ port, repoDir }: {
|
|
5
6
|
port: number;
|
|
7
|
+
repoDir: string;
|
|
6
8
|
});
|
|
7
9
|
setFilePath(filePath: string): void;
|
|
8
10
|
startFileService(): Promise<number>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/file/server.ts"],"names":[],"mappings":"AAUA,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/file/server.ts"],"names":[],"mappings":"AAUA,qBAAa,WAAW;IACtB,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,OAAO,CAAc;gBAEjB,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;IAKhE,WAAW,CAAC,QAAQ,EAAE,MAAM;IAItB,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;CAwC1C;AAED,wBAAsB,gBAAgB,kBAAK"}
|
package/dist/file/server.js
CHANGED
|
@@ -9,10 +9,12 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
10
10
|
const web_1 = require("../bin/utils/platform/web");
|
|
11
11
|
class FileService {
|
|
12
|
-
filePath = "";
|
|
13
12
|
port = 0;
|
|
14
|
-
|
|
13
|
+
filePath = "";
|
|
14
|
+
repoDir = "";
|
|
15
|
+
constructor({ port, repoDir }) {
|
|
15
16
|
this.port = port;
|
|
17
|
+
this.repoDir = repoDir;
|
|
16
18
|
}
|
|
17
19
|
setFilePath(filePath) {
|
|
18
20
|
this.filePath = filePath;
|
|
@@ -23,11 +25,11 @@ class FileService {
|
|
|
23
25
|
app.post("/test", async (req, res) => {
|
|
24
26
|
const { generatedCode, importPaths } = req.body;
|
|
25
27
|
try {
|
|
26
|
-
const testFilePath = path_1.default.resolve(
|
|
28
|
+
const testFilePath = path_1.default.resolve(this.repoDir, this.filePath);
|
|
27
29
|
if (testFilePath) {
|
|
28
30
|
const testFile = fs_1.default.readFileSync(testFilePath, "utf-8");
|
|
29
31
|
const newContents = (0, web_1.replaceCreateTestWithNewCode)(testFilePath, testFile, generatedCode);
|
|
30
|
-
const importStatements = await (0, web_1.importAllExportsStmtFromFilePaths)(importPaths, this.filePath);
|
|
32
|
+
const importStatements = await (0, web_1.importAllExportsStmtFromFilePaths)(this.repoDir, importPaths, this.filePath);
|
|
31
33
|
fs_1.default.writeFileSync(testFilePath, `${importStatements.join("\n")}\n${newContents}`, "utf-8");
|
|
32
34
|
await (0, web_1.lintErrors)(testFilePath);
|
|
33
35
|
return res.send({ success: true });
|
package/dist/initSentry.js
CHANGED
|
@@ -25,7 +25,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
const Sentry = __importStar(require("@sentry/node"));
|
|
27
27
|
Sentry.init({
|
|
28
|
-
enabled: process.env.NODE_ENV
|
|
28
|
+
enabled: process.env.NODE_ENV === "production",
|
|
29
29
|
dsn: "https://87e61b11ede1431d7156bcd26da997cc@o4506822020235264.ingest.us.sentry.io/4508806031015936",
|
|
30
30
|
tracesSampleRate: 1.0,
|
|
31
31
|
serverName: "test-gen",
|
package/dist/reporter/index.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ export declare function getReporter(): Reporter | undefined;
|
|
|
17
17
|
*/
|
|
18
18
|
export declare function setReporterConfig(config: ReporterConfigType): void;
|
|
19
19
|
export declare class TestGenUpdatesReporter {
|
|
20
|
+
private repoDir;
|
|
20
21
|
constructor();
|
|
21
22
|
sendGenTrace(trace: string): Promise<void>;
|
|
22
23
|
reportGenAssets({ projectRepoName, testName, }: {
|
|
@@ -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;CACzB,CAAC;AAKF,wBAAgB,WAAW,IAAI,QAAQ,GAAG,SAAS,CAUlD;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAGlE;AAED,qBAAa,sBAAsB;;
|
|
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;CACzB,CAAC;AAKF,wBAAgB,WAAW,IAAI,QAAQ,GAAG,SAAS,CAUlD;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAGlE;AAED,qBAAa,sBAAsB;IACjC,OAAO,CAAC,OAAO,CAAS;;IAKlB,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;IAiDK,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA8C9C,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAY3C,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAY1C,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAWxD"}
|
package/dist/reporter/index.js
CHANGED
|
@@ -40,7 +40,10 @@ function setReporterConfig(config) {
|
|
|
40
40
|
}
|
|
41
41
|
exports.setReporterConfig = setReporterConfig;
|
|
42
42
|
class TestGenUpdatesReporter {
|
|
43
|
-
|
|
43
|
+
repoDir;
|
|
44
|
+
constructor() {
|
|
45
|
+
this.repoDir = process.cwd();
|
|
46
|
+
}
|
|
44
47
|
async sendGenTrace(trace) {
|
|
45
48
|
console.log("trace", trace);
|
|
46
49
|
// upload trace to r2 and report it to reporter
|
|
@@ -56,6 +59,7 @@ class TestGenUpdatesReporter {
|
|
|
56
59
|
const { videoUrls, traceFiles } = await (0, uploader_1.uploadTestResultsUsingPrjRepo)({
|
|
57
60
|
projectRepoName,
|
|
58
61
|
testName,
|
|
62
|
+
repoDir: this.repoDir,
|
|
59
63
|
});
|
|
60
64
|
const reporter = getReporter();
|
|
61
65
|
const message = {
|
|
@@ -101,24 +105,26 @@ class TestGenUpdatesReporter {
|
|
|
101
105
|
}
|
|
102
106
|
try {
|
|
103
107
|
// upload current screenshot to r2 and report it to reporter
|
|
104
|
-
if (!fs_extra_1.default.existsSync(path_1.default.join(
|
|
105
|
-
await fs_extra_1.default.mkdir(
|
|
108
|
+
if (!fs_extra_1.default.existsSync(path_1.default.join(this.repoDir, "gen-assets"))) {
|
|
109
|
+
await fs_extra_1.default.mkdir(this.repoDir, "gen-assets");
|
|
106
110
|
}
|
|
107
|
-
await fs_extra_1.default.writeFile(path_1.default.join(
|
|
111
|
+
await fs_extra_1.default.writeFile(path_1.default.join(this.repoDir, "gen-assets", `current-view-${Date.now()}.png`), buffer);
|
|
108
112
|
const uploadDir = (0, uploader_1.getUploadPathForRun)(reporterConfig?.projectRepoName);
|
|
109
113
|
const files = await (0, r2_uploader_1.uploadDirectory)({
|
|
110
|
-
sourceDir: path_1.default.join(
|
|
114
|
+
sourceDir: path_1.default.join(this.repoDir, "gen-assets"),
|
|
111
115
|
destinationDir: uploadDir,
|
|
112
116
|
uploadBucket: uploader_1.UPLOAD_BUCKET,
|
|
113
117
|
});
|
|
114
118
|
const filePath = Object.keys(files)[0];
|
|
115
|
-
const relativeFilePath = filePath.replace(path_1.default.join(
|
|
119
|
+
const relativeFilePath = filePath.replace(path_1.default.join(this.repoDir, "gen-assets"), "");
|
|
116
120
|
const url = `${uploader_1.UPLOAD_DOMAIN}/${uploadDir}${relativeFilePath}`;
|
|
117
121
|
await getReporter()?.report(new reporter_1.ProcessLogMessageBuilder({
|
|
118
122
|
type: "current-snapshot",
|
|
119
123
|
message: JSON.stringify({ type: "current-view", url }),
|
|
120
124
|
}));
|
|
121
|
-
await fs_extra_1.default.rmdir((
|
|
125
|
+
await fs_extra_1.default.rmdir(path_1.default.join(this.repoDir, "gen-assets"), {
|
|
126
|
+
recursive: true,
|
|
127
|
+
});
|
|
122
128
|
}
|
|
123
129
|
catch (e) {
|
|
124
130
|
console.warn("Failed to upload current view screenshot", e);
|
package/dist/uploader/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export declare const UPLOAD_BUCKET = "test-report";
|
|
2
2
|
export declare const UPLOAD_DOMAIN = "https://reports.empirical.run";
|
|
3
|
-
export declare function getFullUploadPath(filePath: string, uploadDir: string): string;
|
|
4
|
-
export declare function getRelativeUploadPath(filePath: string): string;
|
|
3
|
+
export declare function getFullUploadPath(repoDir: string, filePath: string, uploadDir: string): string;
|
|
4
|
+
export declare function getRelativeUploadPath(filePath: string, repoDir: string): string;
|
|
5
5
|
/**
|
|
6
6
|
* Function to upload test results to R2 using the project repo name and test name.
|
|
7
7
|
* This function uploads both the JSON summary of test results and associated video files.
|
|
@@ -12,9 +12,10 @@ export declare function getRelativeUploadPath(filePath: string): string;
|
|
|
12
12
|
* @returns {string[]} returns.videoUrls - URLs of the uploaded video files.
|
|
13
13
|
* @returns {string} returns.summaryUrl - URL of the uploaded summary JSON file.
|
|
14
14
|
*/
|
|
15
|
-
export declare function uploadTestResultsUsingPrjRepo({ projectRepoName, testName, }: {
|
|
15
|
+
export declare function uploadTestResultsUsingPrjRepo({ projectRepoName, testName, repoDir, }: {
|
|
16
16
|
projectRepoName: string;
|
|
17
17
|
testName: string;
|
|
18
|
+
repoDir: string;
|
|
18
19
|
}): Promise<{
|
|
19
20
|
videoUrls: string[];
|
|
20
21
|
summaryUrl: string;
|
|
@@ -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,
|
|
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,CAC/B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,UAKlB;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,UAEtE;AAED;;;;;;;;;GASG;AACH,wBAAsB,6BAA6B,CAAC,EAClD,eAAe,EACf,QAAQ,EACR,OAAO,GACR,EAAE;IACD,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC;IACV,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC,CAgED;AAED,wBAAgB,mBAAmB,CAAC,eAAe,EAAE,MAAM,UAM1D;AAED,wBAAgB,2BAA2B,uBAQ1C"}
|
package/dist/uploader/index.js
CHANGED
|
@@ -16,14 +16,14 @@ const PLAYWRIGHT_REPORT_DATA = "playwright-report/data";
|
|
|
16
16
|
exports.UPLOAD_BUCKET = "test-report";
|
|
17
17
|
exports.UPLOAD_DOMAIN = "https://reports.empirical.run"; // domain based on bucket mentioned above
|
|
18
18
|
const uploadId = crypto.randomUUID();
|
|
19
|
-
function getFullUploadPath(filePath, uploadDir) {
|
|
19
|
+
function getFullUploadPath(repoDir, filePath, uploadDir) {
|
|
20
20
|
// remove the source dir from the file path - only keep the relative path
|
|
21
|
-
const relativeFilePath = getRelativeUploadPath(filePath);
|
|
21
|
+
const relativeFilePath = getRelativeUploadPath(filePath, repoDir);
|
|
22
22
|
return `${exports.UPLOAD_DOMAIN}/${uploadDir}${relativeFilePath}`;
|
|
23
23
|
}
|
|
24
24
|
exports.getFullUploadPath = getFullUploadPath;
|
|
25
|
-
function getRelativeUploadPath(filePath) {
|
|
26
|
-
return filePath.replace(path_1.default.join(
|
|
25
|
+
function getRelativeUploadPath(filePath, repoDir) {
|
|
26
|
+
return filePath.replace(path_1.default.join(repoDir, PLAYWRIGHT_REPORT_DATA), "");
|
|
27
27
|
}
|
|
28
28
|
exports.getRelativeUploadPath = getRelativeUploadPath;
|
|
29
29
|
/**
|
|
@@ -36,25 +36,25 @@ exports.getRelativeUploadPath = getRelativeUploadPath;
|
|
|
36
36
|
* @returns {string[]} returns.videoUrls - URLs of the uploaded video files.
|
|
37
37
|
* @returns {string} returns.summaryUrl - URL of the uploaded summary JSON file.
|
|
38
38
|
*/
|
|
39
|
-
async function uploadTestResultsUsingPrjRepo({ projectRepoName, testName, }) {
|
|
39
|
+
async function uploadTestResultsUsingPrjRepo({ projectRepoName, testName, repoDir, }) {
|
|
40
40
|
const uploadDir = getUploadPathForRun(projectRepoName);
|
|
41
|
-
console.log("Current directory for assets upload",
|
|
41
|
+
console.log("Current directory for assets upload", repoDir);
|
|
42
42
|
const files = await (0, r2_uploader_1.uploadDirectory)({
|
|
43
|
-
sourceDir: path_1.default.join(
|
|
43
|
+
sourceDir: path_1.default.join(repoDir, PLAYWRIGHT_REPORT_DATA),
|
|
44
44
|
destinationDir: uploadDir,
|
|
45
45
|
uploadBucket: exports.UPLOAD_BUCKET,
|
|
46
46
|
});
|
|
47
47
|
// upload summary.json
|
|
48
48
|
await (0, r2_uploader_1.uploadDirectory)({
|
|
49
|
-
sourceDir: path_1.default.join(
|
|
50
|
-
fileList: [path_1.default.join(
|
|
49
|
+
sourceDir: path_1.default.join(repoDir, "playwright-report"),
|
|
50
|
+
fileList: [path_1.default.join(repoDir, "playwright-report", "summary.json")],
|
|
51
51
|
destinationDir: uploadDir,
|
|
52
52
|
uploadBucket: exports.UPLOAD_BUCKET,
|
|
53
53
|
});
|
|
54
54
|
// fileNames are relative upload paths
|
|
55
55
|
const fileNames = Object.keys(files);
|
|
56
|
-
console.log("Uploaded files", fileNames.map((f) => getFullUploadPath(f, uploadDir)));
|
|
57
|
-
const defaultLocation = path_1.default.join(
|
|
56
|
+
console.log("Uploaded files", fileNames.map((f) => getFullUploadPath(repoDir, f, uploadDir)));
|
|
57
|
+
const defaultLocation = path_1.default.join(repoDir, "playwright-report", "summary.json");
|
|
58
58
|
const results = (0, reporter_1.parseJsonReport)(defaultLocation);
|
|
59
59
|
const flatTestsList = (0, reporter_1.getFlattenedTestList)(results.suites);
|
|
60
60
|
const testAttachmentPaths = [];
|
|
@@ -65,7 +65,7 @@ async function uploadTestResultsUsingPrjRepo({ projectRepoName, testName, }) {
|
|
|
65
65
|
// results array is basically made by retries
|
|
66
66
|
for (const attachments of test.tests[0].results[0].attachments) {
|
|
67
67
|
if (attachments.path) {
|
|
68
|
-
testAttachmentPaths.push(getRelativeUploadPath(attachments.path));
|
|
68
|
+
testAttachmentPaths.push(getRelativeUploadPath(attachments.path, repoDir));
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
}
|
|
@@ -78,11 +78,11 @@ async function uploadTestResultsUsingPrjRepo({ projectRepoName, testName, }) {
|
|
|
78
78
|
console.log("traceFiles", traceFiles);
|
|
79
79
|
return {
|
|
80
80
|
videoUrls: videoFiles
|
|
81
|
-
.map((fileName) => getFullUploadPath(fileName, uploadDir))
|
|
81
|
+
.map((fileName) => getFullUploadPath(repoDir, fileName, uploadDir))
|
|
82
82
|
.filter((url) => !!url),
|
|
83
83
|
summaryUrl: `${exports.UPLOAD_DOMAIN}/${uploadDir}/summary.json`,
|
|
84
84
|
traceFiles: traceFiles
|
|
85
|
-
.map((fileName) => getFullUploadPath(fileName, uploadDir))
|
|
85
|
+
.map((fileName) => getFullUploadPath(repoDir, fileName, uploadDir))
|
|
86
86
|
.filter((url) => !!url),
|
|
87
87
|
};
|
|
88
88
|
}
|
package/dist/utils/pw-test.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pw-test.d.ts","sourceRoot":"","sources":["../../src/utils/pw-test.ts"],"names":[],"mappings":"AAEA,wBAAsB,4BAA4B,
|
|
1
|
+
{"version":3,"file":"pw-test.d.ts","sourceRoot":"","sources":["../../src/utils/pw-test.ts"],"names":[],"mappings":"AAEA,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,GAAG,CAAC,CAKd;AAED,wBAAsB,QAAQ,kBAS7B"}
|
package/dist/utils/pw-test.js
CHANGED
|
@@ -5,17 +5,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.skipTest = exports.getTestFixtureModuleFromRepo = void 0;
|
|
7
7
|
const api_1 = __importDefault(require("tsx/cjs/api"));
|
|
8
|
-
async function getTestFixtureModuleFromRepo() {
|
|
9
|
-
const [lastDir] =
|
|
10
|
-
const dir = `${
|
|
8
|
+
async function getTestFixtureModuleFromRepo(repoDir) {
|
|
9
|
+
const [lastDir] = repoDir.split("/").reverse();
|
|
10
|
+
const dir = `${repoDir}/${lastDir}`;
|
|
11
11
|
const { test } = await api_1.default.require(`./tests/fixtures.ts`, dir);
|
|
12
12
|
return test;
|
|
13
13
|
}
|
|
14
14
|
exports.getTestFixtureModuleFromRepo = getTestFixtureModuleFromRepo;
|
|
15
15
|
async function skipTest() {
|
|
16
16
|
let test;
|
|
17
|
+
let repoDir = process.cwd();
|
|
17
18
|
try {
|
|
18
|
-
test = await getTestFixtureModuleFromRepo();
|
|
19
|
+
test = await getTestFixtureModuleFromRepo(repoDir);
|
|
19
20
|
}
|
|
20
21
|
catch (e) {
|
|
21
22
|
console.error("Error while importing fixture module to extract test:", e);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@empiricalrun/test-gen",
|
|
3
|
-
"version": "0.43.
|
|
3
|
+
"version": "0.43.2",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"registry": "https://registry.npmjs.org/",
|
|
6
6
|
"access": "public"
|
|
@@ -72,8 +72,8 @@
|
|
|
72
72
|
"ts-morph": "^23.0.0",
|
|
73
73
|
"tsx": "^4.16.2",
|
|
74
74
|
"typescript": "^5.3.3",
|
|
75
|
-
"@empiricalrun/llm": "^0.9.35",
|
|
76
75
|
"@empiricalrun/r2-uploader": "^0.3.8",
|
|
76
|
+
"@empiricalrun/llm": "^0.9.35",
|
|
77
77
|
"@empiricalrun/reporter": "^0.23.1"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|