@empiricalrun/test-gen 0.43.1 → 0.43.3

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.
Files changed (59) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/actions/skill.d.ts.map +1 -1
  3. package/dist/actions/skill.js +1 -0
  4. package/dist/agent/browsing/run.d.ts +3 -16
  5. package/dist/agent/browsing/run.d.ts.map +1 -1
  6. package/dist/agent/browsing/run.js +9 -10
  7. package/dist/agent/browsing/utils.d.ts +1 -1
  8. package/dist/agent/browsing/utils.d.ts.map +1 -1
  9. package/dist/agent/browsing/utils.js +3 -3
  10. package/dist/agent/master/action-tool-calls.d.ts.map +1 -1
  11. package/dist/agent/master/action-tool-calls.js +2 -1
  12. package/dist/agent/master/browser-tests/index.spec.js +1 -1
  13. package/dist/agent/master/next-action.d.ts.map +1 -1
  14. package/dist/agent/master/next-action.js +5 -2
  15. package/dist/agent/master/run.d.ts.map +1 -1
  16. package/dist/agent/master/run.js +5 -0
  17. package/dist/agent/planner/run.d.ts +1 -1
  18. package/dist/agent/planner/run.d.ts.map +1 -1
  19. package/dist/agent/planner/run.js +91 -28
  20. package/dist/bin/index.js +33 -16
  21. package/dist/bin/utils/index.d.ts +7 -5
  22. package/dist/bin/utils/index.d.ts.map +1 -1
  23. package/dist/bin/utils/index.js +10 -26
  24. package/dist/bin/utils/platform/web/index.d.ts +1 -1
  25. package/dist/bin/utils/platform/web/index.d.ts.map +1 -1
  26. package/dist/bin/utils/platform/web/index.js +2 -2
  27. package/dist/bin/utils/scenarios/index.d.ts +3 -0
  28. package/dist/bin/utils/scenarios/index.d.ts.map +1 -1
  29. package/dist/bin/utils/scenarios/index.js +33 -1
  30. package/dist/browser-injected-scripts/annotate-elements.spec.js +22 -0
  31. package/dist/browser-injected-scripts/annotate-elements.spec.ts +32 -0
  32. package/dist/file/client.d.ts +1 -0
  33. package/dist/file/client.d.ts.map +1 -1
  34. package/dist/file/client.js +16 -0
  35. package/dist/file/server.d.ts +4 -2
  36. package/dist/file/server.d.ts.map +1 -1
  37. package/dist/file/server.js +8 -4
  38. package/dist/human-in-the-loop/cli.d.ts +2 -0
  39. package/dist/human-in-the-loop/cli.d.ts.map +1 -0
  40. package/dist/human-in-the-loop/cli.js +24 -0
  41. package/dist/human-in-the-loop/index.d.ts +10 -0
  42. package/dist/human-in-the-loop/index.d.ts.map +1 -0
  43. package/dist/human-in-the-loop/index.js +24 -0
  44. package/dist/human-in-the-loop/ipc.d.ts +4 -0
  45. package/dist/human-in-the-loop/ipc.d.ts.map +1 -0
  46. package/dist/human-in-the-loop/ipc.js +48 -0
  47. package/dist/initSentry.js +1 -1
  48. package/dist/prompts/lib/ts-transformer.d.ts.map +1 -1
  49. package/dist/prompts/lib/ts-transformer.js +3 -1
  50. package/dist/reporter/index.d.ts +1 -0
  51. package/dist/reporter/index.d.ts.map +1 -1
  52. package/dist/reporter/index.js +13 -7
  53. package/dist/uploader/index.d.ts +4 -3
  54. package/dist/uploader/index.d.ts.map +1 -1
  55. package/dist/uploader/index.js +14 -14
  56. package/dist/utils/pw-test.d.ts +1 -1
  57. package/dist/utils/pw-test.d.ts.map +1 -1
  58. package/dist/utils/pw-test.js +5 -4
  59. package/package.json +2 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @empiricalrun/test-gen
2
2
 
3
+ ## 0.43.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 0b4cffa: feat: add human in the loop for planner
8
+ - 694e202: fix: report gen assets should not throw in cli
9
+
10
+ ## 0.43.2
11
+
12
+ ### Patch Changes
13
+
14
+ - 5334ba8: test: added failing test for multiple annotations for buttons
15
+ - 385d2c6: fix: disable sentry for local development environment
16
+ - 7b47902: chore: reduce assumptions of repo dir being process.cwd
17
+ - 1d0a746: feat: new cli args for --name, --file, and --prompt
18
+ - 0f342af: fix: break master agent loop if element is not visible after scroll
19
+
3
20
  ## 0.43.1
4
21
 
5
22
  ### 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,yBAmHlC,CAAC"}
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"}
@@ -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":"AAoBA,KAAK,iBAAiB,GAAG;IACvB;;;;OAIG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAsB,6BAA6B,CAAC,EAClD,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,GACjB,EAAE,iBAAiB,iBA8EnB"}
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 utils_2 = require("./utils");
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, utils_2.canRunMasterAgent)(testFilePath);
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, utils_2.readPlaywrightConfig)();
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, utils_2.detectProjectName)(testFilePath, playwrightConfig, pwProjectsFilter);
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 = `${process.cwd()}/tests`;
65
+ const testsDirectory = `${repoDir}/tests`;
67
66
  const isTestRunTriggeredForTeardown = teardownFileRegex.test(testFilePath);
68
- const teardowns = new utils_2.TeardownManager(testsDirectory);
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: (0, utils_1.getTestConfigCliArg)(),
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,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAM1E;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"}
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] = process.cwd().split("/").reverse();
291
- const playwrightConfig = (await api_1.default.require("./playwright.config.ts", `${process.cwd()}/${lastDir}`)).default;
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,CAEpE;AAyDD,wBAAgB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAoCjC"}
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.skip("scroll when element does not exist", async ({ page }) => {
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,CAsLA"}
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 === 0) {
171
- throw new Error("Agent is not able to figure out the next action, since element is not visible on screen.");
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;;;GAsWA"}
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"}
@@ -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",
@@ -3,5 +3,5 @@ export declare function planTask({ task, specPath, trace, }: {
3
3
  task: string;
4
4
  specPath: string;
5
5
  trace?: TraceClient;
6
- }): Promise<string>;
6
+ }): Promise<any>;
7
7
  //# sourceMappingURL=run.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/planner/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,WAAW,EAAE,MAAM,mBAAmB,CAAC;AA4BpE,wBAAsB,QAAQ,CAAC,EAC7B,IAAI,EACJ,QAAQ,EACR,KAAK,GACN,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,mBAyCA"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/planner/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAapE,wBAAsB,QAAQ,CAAC,EAC7B,IAAI,EACJ,QAAQ,EACR,KAAK,GACN,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,gBA0HA"}
@@ -3,24 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.planTask = void 0;
4
4
  const llm_1 = require("@empiricalrun/llm");
5
5
  const context_1 = require("../../bin/utils/context");
6
- const promptTemplate_0 = "{{#section \"system\"}}\nYou are an expert software engineer in test. You are given a task to provide a high level plan to create a test for a\ngiven scenario.\n\nYou will be provided with already added tests and page object object models which you can use to plan out how to write\nthe test.\n\nThe expected plan should be a list of bullet points and each bullet point is a step in the test.\nYou will be provided with app knowledge as well, which can help you groom the steps in the tests.\n{{/section}}\n\n{{#section \"user\"}}\nApp knowledge\n{{appKnowledge}}\n\n-----\n\nCurrent tests and page object model references\n\n{{fileContext}}\n\n------\n\nTask:\n\n{{task}}\n\n------\n\nFollow the steps to create a test plan:\n- create sub tasks\n- read the task step by step and create sub tasks from the given task\n- Ensure no new steps are added which are not mentioned in the task\n- enriched sub tasks\n- Read the app knowledge provided to you and enrich the verified sub tasks based on the provided information in app\nknowledge.\n- Fill in the missing information in the verified sub tasks based on the app knowledge.\n- based on the type of task, add sub tasks to the verified sub tasks based on the matching criteria\n- final plan:\n- Once all the subtasks are enriched, list all the sub tasks as bullet points\n- Each bullet point should be one of the following actions:\n- Open page, Click on, Fill in, Assert, hover on, press, extract textContent\n- Do not respond with points which do not start with above actions.\n\nFollow the steps before responding\n- The steps should only contain bullet points on list of steps for the test\n- Do not add any other assertion which is not mentioned in the task or app knowledge\n- Respond with <create_sub_tasks></create_sub_tasks>\n<enriched_sub_tasks></enriched_sub_tasks> and <final_plan></final_plan>\n- The final plan should not mention reference to the knowledge base used to generate it\n{{/section}}";
7
- function extractTestPlan(input) {
8
- const result = {
9
- createSubTasks: "",
10
- verfiedSubTasks: "",
11
- enrichedSubTasks: "",
12
- finalPlan: "",
13
- };
14
- const regex = /<create_sub_tasks>([\s\S]*?)<\/create_sub_tasks>[\s\S]*?<enriched_sub_tasks>([\s\S]*?)<\/enriched_sub_tasks>[\s\S]*?<final_plan>([\s\S]*?)<\/final_plan>/g;
15
- let match;
16
- while ((match = regex.exec(input)) !== null) {
17
- const [, createSubTasks, enrichedSubTasks, finalPlan] = match;
18
- result.createSubTasks = createSubTasks?.trim() || "";
19
- result.enrichedSubTasks = enrichedSubTasks?.trim() || "";
20
- result.finalPlan = finalPlan?.trim() || "";
21
- }
22
- return result;
23
- }
6
+ const human_in_the_loop_1 = require("../../human-in-the-loop");
7
+ const promptTemplate_0 = "{{#section \"system\"}}\nYou are an expert software engineer in test and have capability to collaborate with user to generate a test plan.\nYou are given a task to provide a high level plan to create a test for a given scenario.\n\nYou will be provided with already added Playwright tests and page object object models which you can use generate the test plan.\nTest plan should be a list of bullet points and each bullet point representing each test step.\nYou will be provided with app knowledge which can help you groom the steps in the plan.\n\n{{#if humanLoopRequired}}\nDo NOT finish until you have a complete understanding of the plan and have all the minute details of how the test should look like.\n\nALWAYS VERIFY THE PLAN WITH USER BEFORE FINISHING. THE USER SHOULD BE ABLE TO REVIEW AND GIVE GO AHEAD TO THE PLAN.\n\nDO NOT FINISH UNTIL USER EXPLICITLY CONFIRMS THE PLAN IS GOOD TO GO.\n{{/if}}\n\n### Test Plan Creation Guidelines\n\n- **Create Subtasks:**\n - Read the task step by step and create subtasks from the given task.\n - Do not add any new steps that are not mentioned in the task.\n\n- **Enrich Subtasks:**\n - Read the provided app knowledge.\n - Enrich the subtasks based on the information from the app knowledge.\n\n- **Plan:**\n - Once all subtasks are enriched, list them as bullet points.\n - Each bullet point must start with one of the following actions: \n - Open page \n - Click on \n - Fill in \n - Assert \n - Hover on \n - Press \n - Extract textContent\n - Do not include any bullet points that do not start with the above actions.\n\n- **Additional Notes:**\n - The final output should only contain bullet points listing the test steps.\n - Do not add any assertions that are not mentioned in the task or app knowledge.\n - The plan should not reference the knowledge base used to generate it.\n\n{{/section}}\n\n{{#section \"user\"}}\n\nApp knowledge:\n{{appKnowledge}}\n\n-----\n\nCurrent tests and page object model references:\n{{fileContext}}\n\n------\n\nTask:\n{{task}}\n\n------\n{{/section}}";
24
8
  async function planTask({ task, specPath, trace, }) {
25
9
  let fileContext = "";
26
10
  try {
@@ -39,27 +23,106 @@ ${pomPrompt}
39
23
  task,
40
24
  },
41
25
  });
26
+ // if the code in running in ci worker or github actions, disable human loop
27
+ const humanLoopRequired = process.env.CI !== "true";
42
28
  const appKnowledge = await (0, context_1.fetchAppKnowledge)();
43
29
  const messages = (0, llm_1.compilePrompt)(promptTemplate_0, {
44
30
  appKnowledge,
45
31
  fileContext,
46
32
  task,
33
+ humanLoopRequired,
47
34
  });
48
35
  const llm = new llm_1.LLM({
49
36
  provider: "openai",
50
- //TODO: change to o1
51
37
  defaultModel: "gpt-4o",
52
38
  });
53
- const response = await llm.createChatCompletion({
54
- trace: plannerSpan,
55
- traceName: "planner-llm",
56
- messages,
57
- modelParameters: {
58
- temperature: 0.5,
39
+ let maxRetries = 10;
40
+ // TODO: this should be environment driven
41
+ const hl = new human_in_the_loop_1.HumanLoop({ method: "ipc" });
42
+ const tools = [
43
+ {
44
+ type: "function",
45
+ function: {
46
+ name: "finish",
47
+ description: "Final output of the conversation",
48
+ parameters: {
49
+ type: "object",
50
+ properties: {
51
+ plan: {
52
+ type: "string",
53
+ description: "Final plan which is verified by the user",
54
+ },
55
+ },
56
+ required: ["plan"],
57
+ additionalProperties: false,
58
+ },
59
+ },
60
+ },
61
+ ];
62
+ if (humanLoopRequired) {
63
+ tools.push({
64
+ type: "function",
65
+ function: {
66
+ name: "send_user_message",
67
+ description: "Send user message",
68
+ parameters: {
69
+ type: "object",
70
+ properties: {
71
+ message: {
72
+ type: "string",
73
+ description: "Message to be sent to the user for any confirmation or clarification",
74
+ },
75
+ },
76
+ required: ["message"],
77
+ additionalProperties: false,
78
+ },
79
+ strict: true,
80
+ },
81
+ });
82
+ }
83
+ while (maxRetries--) {
84
+ const response = await llm.createChatCompletion({
85
+ trace: plannerSpan,
86
+ traceName: "planner-llm",
87
+ messages,
88
+ tools,
89
+ modelParameters: {
90
+ temperature: 0.5,
91
+ tool_choice: "required",
92
+ },
93
+ });
94
+ const toolCall = response?.tool_calls?.[0];
95
+ const respStr = toolCall?.function.arguments;
96
+ const resp = JSON.parse(respStr || "{}");
97
+ // TODO: handle this as a part of actions handler
98
+ if (toolCall?.function.name === "send_user_message") {
99
+ const feedback = await hl.getFeedback({
100
+ message: resp.message,
101
+ });
102
+ messages.push(response);
103
+ messages.push({
104
+ role: "tool",
105
+ tool_call_id: toolCall?.id,
106
+ content: feedback,
107
+ });
108
+ }
109
+ else {
110
+ const plan = resp.plan;
111
+ plannerSpan?.end({
112
+ output: {
113
+ plan,
114
+ },
115
+ });
116
+ return plan;
117
+ }
118
+ }
119
+ // TODO: handle planner failure scenario
120
+ plannerSpan?.end({
121
+ output: {
122
+ plan: "",
123
+ error: "Failed to generate test plan",
59
124
  },
60
125
  });
61
- const plan = extractTestPlan(response?.content || "");
62
- plannerSpan?.end({ output: plan?.finalPlan });
63
- return plan?.finalPlan;
126
+ return "";
64
127
  }
65
128
  exports.planTask = planTask;
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 agent = testGenConfig.options?.agent;
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 ${testGenConfig.options?.agent} agent. ${process.env.LOG_URL ? `[view log](${process.env.LOG_URL})` : ""}`);
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)({
@@ -152,7 +154,8 @@ async function runAgent(testGenConfig, span) {
152
154
  specPath,
153
155
  trace,
154
156
  });
155
- new logger_1.CustomLogger({ useReporter: false }).log("Generated Plan:", plan);
157
+ new logger_1.CustomLogger({ useReporter: false }).log("Generated Plan:");
158
+ console.log(plan);
156
159
  await new reporter_1.TestGenUpdatesReporter().sendMessage(plan);
157
160
  }
158
161
  else if (agent === "code") {
@@ -168,19 +171,30 @@ async function runAgent(testGenConfig, span) {
168
171
  testFilePath: specPath,
169
172
  filePathToUpdate,
170
173
  pwProjectsFilter: testGenConfig.environment?.playwrightProjects,
174
+ testGenToken,
175
+ repoDir: process.cwd(),
171
176
  });
172
177
  }
178
+ return agent;
173
179
  }
174
180
  (async function main() {
175
181
  await Sentry.continueTrace({ sentryTrace: utils_2.sentryTrace, baggage: utils_2.baggage }, async () => {
176
182
  await Sentry.startSpan({ name: "test-gen" }, async (span) => {
177
- // this is where test gen starts executing on giving the command from ci
178
- const logger = new logger_1.CustomLogger({ useReporter: false });
179
- if (process.argv.length < 3) {
180
- logger.error("Please provide path to scenarios using command:", "npx @empiricalrun/test-gen --token <TEST_GEN_TOKEN>");
181
- process.exit(1);
182
- }
183
- const { testGenConfig } = await (0, utils_2.parseCliArgs)();
183
+ const program = new commander_1.Command();
184
+ program
185
+ .option("--token <token>", "Test generation token")
186
+ .option("--name <test-name>", "Name of the test case")
187
+ .option("--prompt <prompt>", "Prompt for the test case")
188
+ .option("--file <test-file>", "File path of the test case (inside tests dir)")
189
+ .parse(process.argv);
190
+ const options = program.opts();
191
+ (0, utils_2.validateCliOptions)(options);
192
+ const testGenConfig = options.token
193
+ ? (0, scenarios_1.loadTestConfigs)(options.token)
194
+ : (0, scenarios_1.buildTestConfigFromOptions)(options);
195
+ const testGenToken = options.token
196
+ ? options.token
197
+ : (0, scenarios_1.buildTokenFromOptions)(options);
184
198
  (0, reporter_1.setReporterConfig)({
185
199
  projectRepoName: testGenConfig.options?.metadata.projectRepoName,
186
200
  testSessionId: testGenConfig.options?.metadata.testSessionId,
@@ -193,10 +207,11 @@ async function runAgent(testGenConfig, span) {
193
207
  projectRepoName: testGenConfig.options?.metadata.projectRepoName,
194
208
  });
195
209
  let testGenFailed = false;
210
+ let agentUsed;
196
211
  try {
197
212
  // download the build if it exists
198
213
  await (0, test_build_1.downloadBuild)(testGenConfig.build || {});
199
- await runAgent(testGenConfig);
214
+ agentUsed = await runAgent(testGenConfig, testGenToken);
200
215
  }
201
216
  catch (e) {
202
217
  span.recordException(e);
@@ -204,9 +219,11 @@ async function runAgent(testGenConfig, span) {
204
219
  testGenFailed = true;
205
220
  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
221
  }
207
- if (testGenConfig.options?.agent !== "code" &&
208
- testGenConfig.options?.agent !== "plan" &&
209
- testGenConfig.testCase.name) {
222
+ if (agentUsed &&
223
+ agentUsed !== "code" &&
224
+ agentUsed !== "plan" &&
225
+ testGenConfig.testCase.name &&
226
+ testGenConfig.options) {
210
227
  await new reporter_1.TestGenUpdatesReporter().reportGenAssets({
211
228
  projectRepoName: testGenConfig.options.metadata.projectRepoName,
212
229
  testName: testGenConfig.testCase.name,
@@ -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,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAKhE,wBAAsB,YAAY;;GAMjC;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAc5C;AAED,eAAO,MAAM,WAAW,oBAA2B,CAAC;AACpD,eAAO,MAAM,OAAO,oBAA6B,CAAC"}
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"}
@@ -1,30 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.baggage = exports.sentryTrace = exports.getTestConfigCliArg = exports.parseCliArgs = void 0;
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,cACjC,MAAM,EAAE,gBACL,MAAM,sBAyBrB,CAAC;AAEF,wBAAsB,qBAAqB,CAAC,EAC1C,YAAY,EACZ,QAAQ,EACR,MAAM,GACP,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,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"}
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(process.cwd(), filePath);
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