@empiricalrun/test-gen 0.30.4 → 0.31.1

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 CHANGED
@@ -1,5 +1,22 @@
1
1
  # @empiricalrun/test-gen
2
2
 
3
+ ## 0.31.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [f317919]
8
+ - @empiricalrun/r2-uploader@0.3.2
9
+
10
+ ## 0.31.0
11
+
12
+ ### Minor Changes
13
+
14
+ - fd3af1f: feat: add support for test file marked serial
15
+
16
+ ### Patch Changes
17
+
18
+ - 6521cb0: fix: add support for method declaration
19
+
3
20
  ## 0.30.4
4
21
 
5
22
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/utils.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAYvD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAK5C,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,MAAM,CAKhD;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,UAIvD;AAsDD;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,aAAa,GACvB,OAAO,CAAC,MAAM,CAAC,CA2CjB;AAyBD,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,IAAI,iBAiBxD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,QA6BjD;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAM1E;AAWD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,oBAAoB,GACrC,OAAO,CAAC,MAAM,CAAC,CA8CjB;AAED,wBAAsB,sBAAsB,CAAC,EAC3C,YAAiB,EACjB,IAAS,EACT,eAAoB,EACpB,gBAAqB,EACrB,UAAyC,GAC1C,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,8EASA"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/utils.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAavD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAK5C,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,MAAM,CAKhD;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,UAIvD;AA0DD;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,aAAa,GACvB,OAAO,CAAC,MAAM,CAAC,CA2CjB;AAyBD,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,IAAI,iBAiBxD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,QA6BjD;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAM1E;AAWD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,oBAAoB,GACrC,OAAO,CAAC,MAAM,CAAC,CA8CjB;AAED,wBAAsB,sBAAsB,CAAC,EAC3C,YAAiB,EACjB,IAAS,EACT,eAAoB,EACpB,gBAAqB,EACrB,UAAyC,GAC1C,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,8EASA"}
@@ -60,9 +60,12 @@ async function prepareFileForUpdateScenario(genConfig) {
60
60
  content: testFileContent,
61
61
  });
62
62
  const parentDescribe = (0, web_1.findFirstSerialDescribeBlock)(testNode);
63
+ const isFileMarkedSerial = await (0, web_1.hasTopLevelDescribeConfigureWithSerialMode)(specPath);
63
64
  // add test.only / describe.only to the spec file so that only that block is executed
64
- const updatedTestFileContent = newContentsWithTestOnly(testFileContent, testBlock, testBlock, parentDescribe?.getText() || "");
65
- await fs_extra_1.default.writeFile(specPath, updatedTestFileContent);
65
+ if (!isFileMarkedSerial) {
66
+ const updatedTestFileContent = newContentsWithTestOnly(testFileContent, testBlock, testBlock, parentDescribe?.getText() || "");
67
+ await fs_extra_1.default.writeFile(specPath, updatedTestFileContent);
68
+ }
66
69
  }
67
70
  /**
68
71
  * Function to prepare test file for master agent to run
@@ -1 +1 @@
1
- {"version":3,"file":"update-flow.d.ts","sourceRoot":"","sources":["../../../src/agent/codegen/update-flow.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAmB3B,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAI7D,KAAK,eAAe,GAAG,QAAQ,GAAG;IAChC,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AAkHF,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,GAAG,SAAS,EACzC,OAAO,GAAE,OAAc,EACvB,QAAQ,GAAE,OAAc,GACvB,OAAO,CAAC,eAAe,EAAE,CAAC,CAuF5B;AAED,wBAAsB,qBAAqB,CAAC,EAC1C,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,KAAK,EACL,aAAoB,GACrB,EAAE;IACD,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAiE7B"}
1
+ {"version":3,"file":"update-flow.d.ts","sourceRoot":"","sources":["../../../src/agent/codegen/update-flow.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAoB3B,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAI7D,KAAK,eAAe,GAAG,QAAQ,GAAG;IAChC,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AAqIF,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,GAAG,SAAS,EACzC,OAAO,GAAE,OAAc,EACvB,QAAQ,GAAE,OAAc,GACvB,OAAO,CAAC,eAAe,EAAE,CAAC,CAuF5B;AAED,wBAAsB,qBAAqB,CAAC,EAC1C,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,KAAK,EACL,aAAoB,GACrB,EAAE;IACD,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAwE7B"}
@@ -10,6 +10,7 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
10
10
  const ts_morph_1 = require("ts-morph");
11
11
  const logger_1 = require("../../bin/logger");
12
12
  const context_1 = require("../../bin/utils/context");
13
+ const fs_1 = require("../../bin/utils/fs");
13
14
  const web_1 = require("../../bin/utils/platform/web");
14
15
  const constants_1 = require("../../constants");
15
16
  const session_1 = require("../../session");
@@ -48,16 +49,33 @@ async function applyFileChanges({ validateTypes = true, trace, testCase, fileCha
48
49
  const project = new ts_morph_1.Project();
49
50
  const sourceFile = project.createSourceFile("updated-code.ts", fileChange.newCode);
50
51
  const functions = sourceFile.getFunctions();
51
- // if there is a single method update in the file
52
+ const checkForMethodSrc = project.createSourceFile("check-method.ts", `class A {
53
+ ${fileChange.newCode}
54
+ }`);
55
+ const methods = checkForMethodSrc.getDescendantsOfKind(ts_morph_1.SyntaxKind.MethodDeclaration);
56
+ const originalSource = project.createSourceFile("current-code.ts", contents);
57
+ // if there is a single function update in the file
52
58
  if (functions.length === 1 &&
53
59
  functions[0]?.getText() === fileChange.newCode) {
54
60
  const updatedCodeFuncNames = functions.map((f) => f.getName());
55
61
  const funcName = updatedCodeFuncNames[0];
56
- const originalSource = project.createSourceFile("current-code.ts", contents);
57
62
  const matchingNodes = originalSource
58
63
  .getDescendantsOfKind(ts_morph_1.SyntaxKind.FunctionDeclaration)
59
64
  .filter((node) => node.getName() === funcName);
60
- contents = contents.replace(matchingNodes[0].getText(), functions[0]?.getText());
65
+ matchingNodes[0]?.replaceWithText(functions[0]?.getText());
66
+ contents = originalSource.getFullText();
67
+ }
68
+ else if (
69
+ // if there is a update in method of a class in the file
70
+ methods.length === 1 &&
71
+ methods[0]?.getText() === fileChange.newCode) {
72
+ const method = methods[0];
73
+ const funcName = method?.getName();
74
+ const matchingNodes = originalSource
75
+ .getDescendantsOfKind(ts_morph_1.SyntaxKind.MethodDeclaration)
76
+ .filter((node) => node.getName() === funcName);
77
+ matchingNodes[0]?.replaceWithText(method?.getText());
78
+ contents = originalSource.getFullText();
61
79
  }
62
80
  else {
63
81
  // since we dont know what is getting updated,
@@ -171,6 +189,13 @@ async function appendCreateTestBlock({ testCase, file, options, trace, validateT
171
189
  const logger = new logger_1.CustomLogger({ useReporter: false });
172
190
  logger.log("Appending create test block");
173
191
  const context = await (0, context_1.contextForGeneration)(file);
192
+ const scenarioFileContent = await fs_extra_1.default.readFile(file, "utf-8");
193
+ const testCodePrompt = (0, fs_1.convertFileContentsToString)([
194
+ {
195
+ filePath: file,
196
+ content: scenarioFileContent,
197
+ },
198
+ ]);
174
199
  const { codePrompt, pomPrompt } = context;
175
200
  const generatedTestCases = [];
176
201
  // TODO: move this to a common place
@@ -191,7 +216,7 @@ async function appendCreateTestBlock({ testCase, file, options, trace, validateT
191
216
  name: "append-create-test-block-prompt",
192
217
  });
193
218
  const instruction = await (0, llm_1.getPrompt)(promptName, {
194
- testFiles: codePrompt,
219
+ testFiles: testCodePrompt,
195
220
  pageFiles: pomPrompt,
196
221
  scenarioName: testCase.name,
197
222
  scenarioSteps: testCase.steps.join("\n"),
package/dist/bin/index.js CHANGED
@@ -63,12 +63,14 @@ async function runAgent(testGenConfig) {
63
63
  sessionId: testGenConfig.options?.metadata.testSessionId,
64
64
  generationId: testGenConfig.options?.metadata.generationId,
65
65
  });
66
+ let testGenFailed = false;
66
67
  try {
67
68
  // download the build if it exists
68
69
  await (0, test_build_1.downloadBuild)(testGenConfig.build || {});
69
70
  await runAgent(testGenConfig);
70
71
  }
71
72
  catch (e) {
73
+ testGenFailed = true;
72
74
  logger.error("Failed to run agent for the scenario", e);
73
75
  }
74
76
  // TODO: move these reporters to a better lifecycle
@@ -76,5 +78,10 @@ async function runAgent(testGenConfig) {
76
78
  await (0, llm_1.flushAllTraces)();
77
79
  await (0, logger_1.waitForLogsToFlush)();
78
80
  await (0, session_1.endSession)();
79
- process.exit(0);
81
+ if (testGenFailed) {
82
+ process.exit(1);
83
+ }
84
+ else {
85
+ process.exit(0);
86
+ }
80
87
  })();
@@ -14,6 +14,7 @@ export declare function getTypescriptTestBlock({ scenarioName, suites, content,
14
14
  testBlock: string | undefined;
15
15
  testNode: Node | undefined;
16
16
  };
17
+ export declare function hasTopLevelDescribeConfigureWithSerialMode(filePath: string): Promise<boolean>;
17
18
  /**
18
19
  * Function to find the first 'describe' block configured with 'serial: true'
19
20
  *
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/bin/utils/platform/web/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,IAAI,EAIL,MAAM,UAAU,CAAC;AAGlB;;;;;;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;CAC5B,CAuCA;AAwBD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,IAAI,GAAG,SAAS,GACrB,IAAI,GAAG,SAAS,CA4BlB;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAG5E;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CA8C7D;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,mCAWjB;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,iBAShD;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,iBAQhD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,UAE5E;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,iBAMpD;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,UAcpD;AAED,wBAAsB,iCAAiC,CAAC,QAAQ,EAAE,MAAM,+BAmBvE;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,UA0CtB;AAED,eAAO,MAAM,6BAA6B;qBAKvB,MAAM;iBACV,MAAM;YACX,MAAM,EAAE;YA2DjB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/bin/utils/platform/web/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,IAAI,EAIL,MAAM,UAAU,CAAC;AAGlB;;;;;;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;CAC5B,CAuCA;AAwBD,wBAAsB,0CAA0C,CAC9D,QAAQ,EAAE,MAAM,oBA+BjB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,IAAI,GAAG,SAAS,GACrB,IAAI,GAAG,SAAS,CA4BlB;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAG5E;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CA8C7D;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,mCAWjB;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,iBAShD;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,iBAQhD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,UAE5E;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,iBAMpD;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,UAcpD;AAED,wBAAsB,iCAAiC,CAAC,QAAQ,EAAE,MAAM,+BAmBvE;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,UA0CtB;AAED,eAAO,MAAM,6BAA6B;qBAKvB,MAAM;iBACV,MAAM;YACX,MAAM,EAAE;YA2DjB,CAAC"}
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.injectCodeSnippetBySuiteChain = exports.replaceCreateTestWithNewCode = exports.getPageVariableNameFromCreateTest = exports.getFixtureImportPath = exports.removeTestOnly = exports.addNewImport = exports.formatCode = exports.lintErrors = exports.stripAndPrependImports = exports.validateTypescript = exports.appendToTestBlock = exports.findFirstSerialDescribeBlock = exports.getTypescriptTestBlock = void 0;
6
+ exports.injectCodeSnippetBySuiteChain = exports.replaceCreateTestWithNewCode = exports.getPageVariableNameFromCreateTest = exports.getFixtureImportPath = exports.removeTestOnly = exports.addNewImport = exports.formatCode = exports.lintErrors = exports.stripAndPrependImports = exports.validateTypescript = exports.appendToTestBlock = exports.findFirstSerialDescribeBlock = exports.hasTopLevelDescribeConfigureWithSerialMode = exports.getTypescriptTestBlock = void 0;
7
7
  const eslint_1 = require("eslint");
8
8
  const fs_extra_1 = __importDefault(require("fs-extra"));
9
9
  const lodash_isequal_1 = __importDefault(require("lodash.isequal"));
@@ -73,6 +73,34 @@ function getParentDescribeNames(node) {
73
73
  }
74
74
  return names.reverse(); // Reverse to get from outermost to innermost
75
75
  }
76
+ async function hasTopLevelDescribeConfigureWithSerialMode(filePath) {
77
+ const project = new ts_morph_1.Project();
78
+ const content = await fs_extra_1.default.readFile(filePath, "utf-8");
79
+ const sourceFile = project.createSourceFile("test.ts", content);
80
+ const statements = sourceFile.getStatements();
81
+ for (const statement of statements) {
82
+ // Check if the statement is an expression statement
83
+ if (statement.getKind() === ts_morph_1.SyntaxKind.ExpressionStatement) {
84
+ const expression = statement.getFirstChildByKind(ts_morph_1.SyntaxKind.CallExpression);
85
+ if (expression) {
86
+ const expressionText = expression.getExpression().getText();
87
+ // Check if it's `test.describe.configure`
88
+ if (expressionText === "test.describe.configure") {
89
+ // Check if arguments exist and if the first argument is an object literal with mode serial
90
+ const args = expression.getArguments();
91
+ const firstArgText = args[0]?.getText();
92
+ if (firstArgText &&
93
+ firstArgText.includes("serial") &&
94
+ firstArgText.includes("mode")) {
95
+ return true;
96
+ }
97
+ }
98
+ }
99
+ }
100
+ }
101
+ return false;
102
+ }
103
+ exports.hasTopLevelDescribeConfigureWithSerialMode = hasTopLevelDescribeConfigureWithSerialMode;
76
104
  /**
77
105
  * Function to find the first 'describe' block configured with 'serial: true'
78
106
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empiricalrun/test-gen",
3
- "version": "0.30.4",
3
+ "version": "0.31.1",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"
@@ -45,7 +45,7 @@
45
45
  "tsx": "^4.16.2",
46
46
  "typescript": "^5.3.3",
47
47
  "@empiricalrun/llm": "^0.9.2",
48
- "@empiricalrun/r2-uploader": "^0.3.1",
48
+ "@empiricalrun/r2-uploader": "^0.3.2",
49
49
  "@empiricalrun/reporter": "^0.20.0"
50
50
  },
51
51
  "devDependencies": {