@empiricalrun/test-gen 0.28.1 → 0.28.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @empiricalrun/test-gen
2
2
 
3
+ ## 0.28.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 5ab2120: Revert "fix: incomplete llm response for ts error fix"
8
+
9
+ ## 0.28.2
10
+
11
+ ### Patch Changes
12
+
13
+ - 90dba16: feat: sanitize html attributes (e.g. style) to reduce input tokens
14
+ - 178d285: fix: use suites information in coding agent for update flow
15
+
3
16
  ## 0.28.1
4
17
 
5
18
  ### 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;AAWvD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAK5C,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,MAAM,CAKhD;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,UAIvD;AAqDD;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,aAAa,GACvB,OAAO,CAAC,MAAM,CAAC,CAkCjB;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;AAWvD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAK5C,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,MAAM,CAKhD;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,UAIvD;AAsDD;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,aAAa,GACvB,OAAO,CAAC,MAAM,CAAC,CAmCjB;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"}
@@ -52,6 +52,7 @@ async function prepareFileForUpdateScenario(genConfig) {
52
52
  testCode: codePrompt,
53
53
  pomCode: pomPrompt,
54
54
  testCase: testCase,
55
+ options: genConfig.options,
55
56
  });
56
57
  const testFileContent = await fs_extra_1.default.readFile(specPath, "utf-8");
57
58
  const { testBlock, testNode } = (0, web_1.getTypescriptTestBlock)({
@@ -70,7 +71,7 @@ async function prepareFileForUpdateScenario(genConfig) {
70
71
  */
71
72
  async function prepareFileForMasterAgent(genConfig) {
72
73
  const { specPath, testCase } = genConfig;
73
- const { name } = testCase;
74
+ const { name, suites } = testCase;
74
75
  // check if the spec file exists
75
76
  // if no then create a new file with test and expect imports
76
77
  if (!fs_extra_1.default.existsSync(specPath)) {
@@ -81,6 +82,7 @@ async function prepareFileForMasterAgent(genConfig) {
81
82
  const existingContents = await fs_extra_1.default.readFile(specPath, "utf-8");
82
83
  const { testBlock } = (0, web_1.getTypescriptTestBlock)({
83
84
  scenarioName: name,
85
+ suites,
84
86
  content: existingContents,
85
87
  });
86
88
  if (!testBlock) {
@@ -1,12 +1,13 @@
1
1
  import { TraceClient } from "@empiricalrun/llm";
2
2
  import { CustomLogger } from "../../bin/logger";
3
- import { TestCase } from "../../types";
4
- export declare function validateAndFixTypescriptErrors({ trace, logger, file, testCode, pomCode, testCase, }: {
3
+ import { TestCase, TestGenConfigOptions } from "../../types";
4
+ export declare function validateAndFixTypescriptErrors({ trace, logger, file, testCode, pomCode, testCase, options, }: {
5
5
  trace?: TraceClient;
6
6
  logger?: CustomLogger;
7
7
  file: string;
8
8
  testCode: string;
9
9
  pomCode: string;
10
10
  testCase: TestCase;
11
+ options?: TestGenConfigOptions;
11
12
  }): Promise<void>;
12
13
  //# sourceMappingURL=fix-ts-errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fix-ts-errors.d.ts","sourceRoot":"","sources":["../../../src/agent/codegen/fix-ts-errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAK3D,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,wBAAsB,8BAA8B,CAAC,EACnD,KAAK,EACL,MAA2B,EAC3B,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,QAAQ,GACT,EAAE;IACD,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,QAAQ,CAAC;CACpB,iBA8DA"}
1
+ {"version":3,"file":"fix-ts-errors.d.ts","sourceRoot":"","sources":["../../../src/agent/codegen/fix-ts-errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAQhD,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAE7D,wBAAsB,8BAA8B,CAAC,EACnD,KAAK,EACL,MAA2B,EAC3B,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,OAAO,GACR,EAAE;IACD,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC,iBAoEA"}
@@ -5,12 +5,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.validateAndFixTypescriptErrors = void 0;
7
7
  const llm_1 = require("@empiricalrun/llm");
8
- const generative_ai_1 = require("@google/generative-ai");
9
8
  const fs_extra_1 = __importDefault(require("fs-extra"));
10
- const remove_markdown_1 = __importDefault(require("remove-markdown"));
11
9
  const logger_1 = require("../../bin/logger");
12
10
  const web_1 = require("../../bin/utils/platform/web");
13
- async function validateAndFixTypescriptErrors({ trace, logger = new logger_1.CustomLogger(), file, testCode, pomCode, testCase, }) {
11
+ const constants_1 = require("../../constants");
12
+ async function validateAndFixTypescriptErrors({ trace, logger = new logger_1.CustomLogger(), file, testCode, pomCode, testCase, options, }) {
14
13
  const validateTypesSpan = trace?.span({ name: "detect-type-errors-in-file" });
15
14
  logger.log("Validating types...");
16
15
  let errors = (0, web_1.validateTypescript)(file);
@@ -44,15 +43,20 @@ async function validateAndFixTypescriptErrors({ trace, logger = new logger_1.Cus
44
43
  scenaioName: testCase.name,
45
44
  });
46
45
  promptSpan?.end({ output: { instruction } });
47
- const genAI = new generative_ai_1.GoogleGenerativeAI(process.env.GOOGLE_API_KEY);
48
- const model = genAI.getGenerativeModel({ model: "gemini-1.5-pro-latest" });
49
- const prompt = instruction.map((p) => p.content);
50
- const llmOutputTrace = trace?.span({ name: "llm-output" });
51
- const message = await model.generateContent(prompt);
52
- llmOutputTrace?.end({ output: { message: message.response.text() } });
53
- const removeMarkdownSpan = trace?.span({ name: "remove-markdown" });
54
- let response = (0, remove_markdown_1.default)(message.response.text() || "");
55
- removeMarkdownSpan?.end({ output: { response } });
46
+ const llm = new llm_1.LLM({
47
+ trace,
48
+ provider: options?.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER,
49
+ defaultModel: options?.model || constants_1.DEFAULT_MODEL,
50
+ providerApiKey: constants_1.MODEL_API_KEYS[options?.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER],
51
+ });
52
+ const message = await llm.createChatCompletion({
53
+ messages: instruction,
54
+ modelParameters: {
55
+ ...constants_1.DEFAULT_MODEL_PARAMETERS,
56
+ ...options?.modelParameters,
57
+ },
58
+ });
59
+ const response = message?.content || "";
56
60
  const readWriteFileSpan = trace?.span({ name: "write-to-file" });
57
61
  await fs_extra_1.default.writeFile(file, response, "utf-8");
58
62
  readWriteFileSpan?.end({ output: { response } });
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/codegen/run.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAI7D,wBAAsB,YAAY,CAChC,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,QAAQ,EAAE,CAAC,CA8FrB"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/codegen/run.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAI7D,wBAAsB,YAAY,CAChC,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,QAAQ,EAAE,CAAC,CAkGrB"}
@@ -25,6 +25,7 @@ async function generateTest(testCase, file, options) {
25
25
  const { testBlock } = (0, web_1.getTypescriptTestBlock)({
26
26
  scenarioName: testCase?.name,
27
27
  content: testFileContent,
28
+ suites: testCase?.suites,
28
29
  });
29
30
  const isUpdate = !!testBlock;
30
31
  if (isUpdate) {
@@ -76,7 +77,7 @@ async function generateTest(testCase, file, options) {
76
77
  logger.success("Test generated successfully!");
77
78
  const readWriteFileSpan = trace.span({ name: "write-to-file" });
78
79
  let contents = fs_extra_1.default.readFileSync(file, "utf-8");
79
- const [prependContent, strippedContent] = await (0, web_1.stripAndPrependImports)(response, testCase?.name);
80
+ const [prependContent, strippedContent] = await (0, web_1.stripAndPrependImports)(response, testCase?.name, testCase?.suites);
80
81
  let updatedContent = prependContent + contents + `\n\n${strippedContent}`;
81
82
  await fs_extra_1.default.writeFile(file, updatedContent, "utf-8");
82
83
  readWriteFileSpan.end({ output: { updatedContent } });
@@ -90,6 +91,7 @@ async function generateTest(testCase, file, options) {
90
91
  testCode: codePrompt,
91
92
  pomCode: pomPrompt,
92
93
  testCase: testCase,
94
+ options,
93
95
  });
94
96
  trace.event({ name: "format-file" });
95
97
  await (0, web_1.formatCode)(file);
@@ -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;AA6GF,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,GAAG,SAAS,EACzC,OAAO,GAAE,OAAc,EACvB,QAAQ,GAAE,OAAc,GACvB,OAAO,CAAC,eAAe,EAAE,CAAC,CA4E5B;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,CAgE7B"}
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;AAmHF,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"}
@@ -15,7 +15,7 @@ const constants_1 = require("../../constants");
15
15
  const session_1 = require("../../session");
16
16
  const fix_ts_errors_1 = require("./fix-ts-errors");
17
17
  const utils_1 = require("./utils");
18
- async function applyFileChanges({ validateTypes = true, trace, testCase, fileChanges, logger, pomPrompt, codePrompt, }) {
18
+ async function applyFileChanges({ validateTypes = true, trace, testCase, fileChanges, logger, testGenOptions, pomPrompt, codePrompt, }) {
19
19
  await Promise.allSettled(fileChanges.map(async (fileChange) => {
20
20
  if (!fileChange.filePath) {
21
21
  return;
@@ -23,17 +23,19 @@ async function applyFileChanges({ validateTypes = true, trace, testCase, fileCha
23
23
  const { testBlock: testBlockUpdate } = (0, web_1.getTypescriptTestBlock)({
24
24
  scenarioName: testCase?.name || "",
25
25
  content: fileChange.newCode || "",
26
+ suites: testCase?.suites,
26
27
  });
27
28
  if (testBlockUpdate) {
28
29
  // assuming the test case getting updated
29
30
  // maintaining the previous accuracy of the test case update
30
31
  const readWriteFileSpan = trace.span({ name: "write-to-file" });
31
32
  let contents = await fs_extra_1.default.readFile(fileChange.filePath, "utf-8");
32
- const [prependContent, strippedContent] = await (0, web_1.stripAndPrependImports)(fileChange.newCode, testCase?.name);
33
+ const [prependContent, strippedContent] = await (0, web_1.stripAndPrependImports)(fileChange.newCode, testCase?.name, testCase?.suites);
33
34
  let updatedContent = prependContent + contents + `\n\n${strippedContent}`;
34
35
  const { testBlock } = (0, web_1.getTypescriptTestBlock)({
35
36
  scenarioName: testCase?.name,
36
37
  content: contents,
38
+ suites: testCase?.suites,
37
39
  });
38
40
  contents = contents.replace(testBlock, `\n\n${strippedContent}`);
39
41
  updatedContent = prependContent + contents;
@@ -75,6 +77,7 @@ async function applyFileChanges({ validateTypes = true, trace, testCase, fileCha
75
77
  testCode: codePrompt,
76
78
  pomCode: pomPrompt,
77
79
  testCase: testCase,
80
+ options: testGenOptions,
78
81
  });
79
82
  }
80
83
  trace.event({ name: "format-file" });
@@ -111,10 +114,19 @@ async function updateTest(testCase, file, options, logging = true, validate = tr
111
114
  name: "update-scenario-prompt",
112
115
  });
113
116
  const promptName = "update-scenario";
117
+ // if describe blocks are present, we need to add them to the scenario name
118
+ // e.g. describe block: login ---> login with email
119
+ // this is help LLM navigate to the right test block
120
+ const scenarioName = testCase.suites?.length
121
+ ? testCase.suites.reduce((text, suite) => {
122
+ text += `Describe block: ${suite} ----> `;
123
+ return text;
124
+ }, "") + testCase.name
125
+ : testCase.name;
114
126
  const instruction = await (0, llm_1.getPrompt)(promptName, {
115
127
  testFiles: codePrompt,
116
128
  pageFiles: pomPrompt,
117
- scenarioName: testCase.name,
129
+ scenarioName,
118
130
  scenarioSteps: testCase.steps.join("\n"),
119
131
  scenarioFile: file,
120
132
  }, 14);
@@ -141,6 +153,7 @@ async function updateTest(testCase, file, options, logging = true, validate = tr
141
153
  testCase,
142
154
  fileChanges,
143
155
  logger,
156
+ testGenOptions: options,
144
157
  pomPrompt: pomPrompt,
145
158
  codePrompt: codePrompt,
146
159
  });
@@ -205,6 +218,7 @@ async function appendCreateTestBlock({ testCase, file, options, trace, validateT
205
218
  testCase,
206
219
  fileChanges,
207
220
  logger,
221
+ testGenOptions: options,
208
222
  pomPrompt: pomPrompt,
209
223
  codePrompt: codePrompt,
210
224
  validateTypes,
@@ -40,7 +40,7 @@ export declare function getTypescriptTestBlock({ scenarioName, suites, content,
40
40
  export declare function findFirstSerialDescribeBlock(node: Node | undefined): Node | undefined;
41
41
  export declare function appendToTestBlock(testBlock: string, content: string): string;
42
42
  export declare function validateTypescript(filePath: string): string[];
43
- export declare function stripAndPrependImports(content: string, testName: string): Promise<(string | undefined)[]>;
43
+ export declare function stripAndPrependImports(content: string, testName: string, suites: string[]): Promise<(string | undefined)[]>;
44
44
  export declare function lintErrors(filePath: string): Promise<void>;
45
45
  export declare function formatCode(filePath: string): Promise<void>;
46
46
  export declare function addNewImport(contents: string, modules: string[], pkg: string): string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/bin/utils/platform/web/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAqB,IAAI,EAAuB,MAAM,UAAU,CAAC;AAGxE;;;;;;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,mCAUjB;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,iBAShD;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,iBAQhD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,UAE5E;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,iBAMpD;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,UAcpD;AAED,wBAAsB,iCAAiC,CAAC,QAAQ,EAAE,MAAM,+BAmBvE;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,UA0CtB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/bin/utils/platform/web/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAqB,IAAI,EAAuB,MAAM,UAAU,CAAC;AAGxE;;;;;;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,EAChB,MAAM,EAAE,MAAM,EAAE,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"}
@@ -166,12 +166,13 @@ function validateTypescript(filePath) {
166
166
  return errors;
167
167
  }
168
168
  exports.validateTypescript = validateTypescript;
169
- async function stripAndPrependImports(content, testName) {
169
+ async function stripAndPrependImports(content, testName, suites) {
170
170
  const importRegexp = /import\s+\{[^}]*\}\s+from\s+["'][^"']+["'];?/g;
171
171
  const imports = content.match(importRegexp);
172
172
  const { testBlock: strippedContent } = getTypescriptTestBlock({
173
173
  scenarioName: testName,
174
174
  content,
175
+ suites,
175
176
  });
176
177
  const prependContent = (imports?.join("\n") || "") + "\n\n";
177
178
  return [prependContent, strippedContent];
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/bin/utils/scenarios/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,aAAa,EAAwB,MAAM,gBAAgB,CAAC;AAU5E,iBAAe,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAc3E;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/bin/utils/scenarios/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,aAAa,EAAwB,MAAM,gBAAgB,CAAC;AAW5E,iBAAe,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAe3E;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}
@@ -11,6 +11,7 @@ async function loadTestConfigs(testGenToken) {
11
11
  name: config.name,
12
12
  steps: config.steps.filter((s) => !!s),
13
13
  group: config.group,
14
+ suites: config.suites,
14
15
  },
15
16
  build: config.build,
16
17
  options: config.options,
@@ -32,6 +32,7 @@ export type TestCase = {
32
32
  name: string;
33
33
  steps: string[];
34
34
  group: string;
35
+ suites: string[];
35
36
  };
36
37
  export type PlaywrightActionGenerator = (page: Page, options?: {
37
38
  stateVariables: Record<string, any>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC;IACzB,KAAK,EAAE,QAAQ,CAAC;IAChB,aAAa,EAAE,WAAW,CAAC;IAC3B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,QAAQ,EAAE;QACR,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;QACxB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,aAAa,GAAG,YAAY,CAAC;KAC3C,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,CACtC,IAAI,EAAE,IAAI,EACV,OAAO,CAAC,EAAE;IACR,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACrC,KACE,MAAM,CAAC;AAEZ,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC;AAEtE,MAAM,MAAM,MAAM,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC5E,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM,CAAC;CAC/E,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC;IACzB,KAAK,EAAE,QAAQ,CAAC;IAChB,aAAa,EAAE,WAAW,CAAC;IAC3B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,QAAQ,EAAE;QACR,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;QACxB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,aAAa,GAAG,YAAY,CAAC;KAC3C,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,CACtC,IAAI,EAAE,IAAI,EACV,OAAO,CAAC,EAAE;IACR,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACrC,KACE,MAAM,CAAC;AAEZ,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC;AAEtE,MAAM,MAAM,MAAM,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC5E,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM,CAAC;CAC/E,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/utils/html.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,QAClB,MAAM,YACF;IACP,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B,WAwBF,CAAC"}
1
+ {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/utils/html.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,QAClB,MAAM,YACF;IACP,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B,WAsCF,CAAC"}
@@ -9,18 +9,32 @@ const sanitizeHtml = (str, options = {}) => {
9
9
  let sanitizedStr = (0, sanitize_html_1.default)(str, {
10
10
  allowedTags: sanitize_html_1.default.defaults.allowedTags.concat([
11
11
  "button",
12
- "form",
13
- "img",
14
- "input",
15
- "select",
16
- "textarea",
17
12
  "div",
13
+ "form",
18
14
  "h1",
19
15
  "h2",
20
16
  "h3",
17
+ "img",
18
+ "input",
21
19
  "label",
20
+ "select",
21
+ "textarea",
22
22
  ]),
23
- allowedAttributes: false,
23
+ allowedAttributes: {
24
+ "*": [
25
+ "alt",
26
+ "aria-*",
27
+ "class",
28
+ "disabled",
29
+ "for",
30
+ "id",
31
+ "href",
32
+ "placeholder",
33
+ "role",
34
+ "selected",
35
+ "src",
36
+ ],
37
+ },
24
38
  });
25
39
  if (options.disallowedStrings) {
26
40
  options.disallowedStrings.forEach((s) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empiricalrun/test-gen",
3
- "version": "0.28.1",
3
+ "version": "0.28.3",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"
@@ -18,7 +18,6 @@
18
18
  "@actions/core": "^1.10.1",
19
19
  "@aws-sdk/client-s3": "^3.614.0",
20
20
  "@aws-sdk/s3-request-presigner": "^3.614.0",
21
- "@google/generative-ai": "^0.15.0",
22
21
  "@playwright/test": "^1.44.1",
23
22
  "@types/sanitize-html": "^2.11.0",
24
23
  "commander": "^12.1.0",
@@ -44,9 +43,9 @@
44
43
  "ts-morph": "^23.0.0",
45
44
  "tsx": "^4.16.2",
46
45
  "typescript": "^5.3.3",
47
- "@empiricalrun/llm": "^0.9.2",
48
46
  "@empiricalrun/r2-uploader": "^0.3.0",
49
- "@empiricalrun/reporter": "^0.18.2"
47
+ "@empiricalrun/reporter": "^0.18.2",
48
+ "@empiricalrun/llm": "^0.9.2"
50
49
  },
51
50
  "devDependencies": {
52
51
  "@types/detect-port": "^1.3.5",