@empiricalrun/test-gen 0.38.4 → 0.38.6

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 (49) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/browser-injected-scripts/annotate-elements.js +541 -159
  3. package/browser-injected-scripts/annotate-elements.spec.ts +2 -2
  4. package/dist/actions/assert.js +3 -3
  5. package/dist/actions/click.js +4 -4
  6. package/dist/actions/fill.js +3 -3
  7. package/dist/actions/goto.d.ts.map +1 -1
  8. package/dist/actions/goto.js +4 -5
  9. package/dist/actions/hover.js +4 -4
  10. package/dist/actions/index.d.ts +4 -2
  11. package/dist/actions/index.d.ts.map +1 -1
  12. package/dist/actions/index.js +13 -1
  13. package/dist/actions/press.js +3 -3
  14. package/dist/actions/skill.d.ts.map +1 -1
  15. package/dist/actions/skill.js +25 -4
  16. package/dist/actions/text-content.js +3 -3
  17. package/dist/actions/utils/index.d.ts.map +1 -1
  18. package/dist/actions/utils/index.js +25 -0
  19. package/dist/agent/browsing/utils.d.ts.map +1 -1
  20. package/dist/agent/browsing/utils.js +71 -3
  21. package/dist/agent/codegen/skills-retriever.d.ts.map +1 -1
  22. package/dist/agent/codegen/skills-retriever.js +36 -1
  23. package/dist/agent/codegen/use-skill.d.ts +2 -1
  24. package/dist/agent/codegen/use-skill.d.ts.map +1 -1
  25. package/dist/agent/codegen/use-skill.js +3 -2
  26. package/dist/agent/master/run.d.ts.map +1 -1
  27. package/dist/agent/master/run.js +43 -24
  28. package/dist/agent/master/with-hints.d.ts +2 -2
  29. package/dist/agent/master/with-hints.d.ts.map +1 -1
  30. package/dist/agent/master/with-hints.js +2 -2
  31. package/dist/agent/planner/run-time-planner.d.ts +20 -0
  32. package/dist/agent/planner/run-time-planner.d.ts.map +1 -0
  33. package/dist/agent/planner/run-time-planner.js +121 -0
  34. package/dist/bin/utils/context.d.ts +1 -1
  35. package/dist/bin/utils/context.d.ts.map +1 -1
  36. package/dist/bin/utils/context.js +1 -1
  37. package/dist/bin/utils/platform/web/index.d.ts +1 -0
  38. package/dist/bin/utils/platform/web/index.d.ts.map +1 -1
  39. package/dist/bin/utils/platform/web/index.js +27 -1
  40. package/dist/browser-injected-scripts/annotate-elements.js +541 -159
  41. package/dist/browser-injected-scripts/annotate-elements.spec.ts +2 -2
  42. package/dist/evals/master-agent.evals.d.ts.map +1 -1
  43. package/dist/evals/master-agent.evals.js +2 -1
  44. package/dist/page/index.d.ts +11 -0
  45. package/dist/page/index.d.ts.map +1 -0
  46. package/dist/page/index.js +16 -0
  47. package/dist/types/index.d.ts +3 -2
  48. package/dist/types/index.d.ts.map +1 -1
  49. package/package.json +1 -1
@@ -6,16 +6,27 @@ const vision_1 = require("@empiricalrun/llm/vision");
6
6
  const actions_1 = require("../../actions");
7
7
  const next_task_1 = require("../../actions/next-task");
8
8
  const skill_1 = require("../../actions/skill");
9
+ const utils_1 = require("../../actions/utils");
9
10
  const logger_1 = require("../../bin/logger");
10
11
  const constants_1 = require("../../constants");
12
+ const page_1 = require("../../page");
11
13
  const reporter_1 = require("../../reporter");
12
14
  const session_1 = require("../../session");
13
15
  const browsing_1 = require("../browsing");
14
- const utils_1 = require("../browsing/utils");
16
+ const utils_2 = require("../browsing/utils");
15
17
  const skills_retriever_1 = require("../codegen/skills-retriever");
16
- const verification_1 = require("../verification");
18
+ const run_time_planner_1 = require("../planner/run-time-planner");
17
19
  const with_hints_1 = require("./with-hints");
18
20
  const MAX_ERROR_COUNT = 2;
21
+ function getPageVariables(stateVariables) {
22
+ const keys = Object.keys(stateVariables);
23
+ const pageVariables = keys.filter((key) => key.endsWith("Page") || key.endsWith("page"));
24
+ const pages = pageVariables.reduce((acc, key) => {
25
+ acc[key] = stateVariables[key];
26
+ return acc;
27
+ }, {});
28
+ return pages;
29
+ }
19
30
  async function getNextAction({ task, executedActions, failedActions, pageUrl, trace, llm, options, pageScreenshot, annotatedPageScreenshot, actions, disableSkills, useHints = false, annotations, }) {
20
31
  const nextActionSpan = trace?.span({
21
32
  name: "master-agent-next-action",
@@ -105,6 +116,7 @@ async function createTestUsingMasterAgent({ task, page, testCase, options, scope
105
116
  const logger = new logger_1.CustomLogger({ useReporter: false });
106
117
  const testgenUpdatesReporter = new reporter_1.TestGenUpdatesReporter();
107
118
  const session = (0, session_1.getSessionDetails)();
119
+ const testGenPage = new page_1.TestGenPage(page, (0, utils_1.getPageVarName)());
108
120
  // add timeout for the page to settle in
109
121
  await page.waitForTimeout(3000);
110
122
  const trace = llm_1.langfuseInstance?.trace({
@@ -141,8 +153,8 @@ async function createTestUsingMasterAgent({ task, page, testCase, options, scope
141
153
  options,
142
154
  });
143
155
  skill_1.testCaseSkills.updateSkills(skills);
144
- const actions = new actions_1.PlaywrightActions(page, scopeVars);
145
- await (0, utils_1.injectPwLocatorGenerator)(page);
156
+ const actions = new actions_1.PlaywrightActions(testGenPage, scopeVars);
157
+ await (0, utils_2.injectPwLocatorGenerator)(page);
146
158
  trace?.update({ input: { task } });
147
159
  let isGivenTaskDone = false;
148
160
  const masterAgentActions = [];
@@ -160,17 +172,25 @@ async function createTestUsingMasterAgent({ task, page, testCase, options, scope
160
172
  failedActions,
161
173
  },
162
174
  });
163
- if (masterAgentActions.length > 0) {
164
- const verificationAgentResp = await (0, verification_1.verificationAgent)({
165
- trace: masterAgentSpan,
166
- task,
167
- conversation: ["Successfully executed actions", ...masterAgentActions],
168
- });
169
- isGivenTaskDone = verificationAgentResp.isDone;
170
- if (isGivenTaskDone) {
171
- await testgenUpdatesReporter.sendMessage(`${verificationAgentResp.reason} Marking the task as done.`);
172
- break;
173
- }
175
+ const plannerResp = await (0, run_time_planner_1.runtimePlanner)({
176
+ trace: masterAgentSpan,
177
+ task,
178
+ conversation: ["Successfully executed actions", ...masterAgentActions],
179
+ pages: getPageVariables(actions.getStateVariables()),
180
+ currentPage: (0, utils_1.getPageVarName)(),
181
+ });
182
+ isGivenTaskDone = plannerResp.isDone;
183
+ if (isGivenTaskDone) {
184
+ await testgenUpdatesReporter.sendMessage(`${plannerResp.reason} Marking the task as done.`);
185
+ break;
186
+ }
187
+ if (actions.getStateVariables()[plannerResp.pageName]) {
188
+ // update page for the master agent
189
+ page = actions.getStateVariables()[plannerResp.pageName];
190
+ // update page in actions
191
+ testGenPage.updatePage({ page, name: plannerResp.pageName });
192
+ // inject scripts in the updated
193
+ await (0, utils_2.injectPwLocatorGenerator)(testGenPage.pwPageInstance);
174
194
  }
175
195
  const buffer = await page.screenshot({
176
196
  //This is done to improve element annotation accuracy, anyways it doesn't annotate elements which are out of viewport
@@ -182,17 +202,17 @@ async function createTestUsingMasterAgent({ task, page, testCase, options, scope
182
202
  const pageScreenshot = buffer.toString("base64");
183
203
  let output;
184
204
  let generatedCodeSteps = [];
185
- let annotations;
186
205
  let annotatedPageScreenshot;
206
+ let annotationKeys = [];
187
207
  if (useHints) {
188
208
  await page.waitForTimeout(2000);
189
- const annotationResult = await page.evaluate(() => {
209
+ annotationKeys = await page.evaluate(() => {
190
210
  // @ts-ignore
191
- window.annotationInstance = window.annotateClickableElements();
211
+ // eslint-disable-next-line no-undef
212
+ window.annotationInstance = annotateClickableElements();
192
213
  // @ts-ignore
193
- return window.annotationInstance;
214
+ return Object.keys(window.annotationInstance.annotations);
194
215
  });
195
- annotations = annotationResult?.annotations || {};
196
216
  await page.waitForTimeout(2000);
197
217
  const annonationBuffer = await page.screenshot({
198
218
  //This is done to improve element annotation accuracy, anyways it doesn't annotate elements which are out of viewport
@@ -216,7 +236,6 @@ async function createTestUsingMasterAgent({ task, page, testCase, options, scope
216
236
  if (await (0, session_1.shouldStopSession)()) {
217
237
  break;
218
238
  }
219
- const annotationKeys = annotations ? Object.keys(annotations) : [];
220
239
  const toolCall = await getNextAction({
221
240
  task,
222
241
  executedActions: masterAgentActions,
@@ -255,13 +274,13 @@ async function createTestUsingMasterAgent({ task, page, testCase, options, scope
255
274
  name: "trigger-hints-flow",
256
275
  input: {
257
276
  outputFromGetNextAction: output,
258
- generatedAnnotations: annotations,
277
+ generatedAnnotations: annotationKeys,
259
278
  },
260
279
  });
261
280
  const result = await (0, with_hints_1.triggerHintsFlow)({
262
281
  outputFromGetNextAction: output,
263
- generatedAnnotations: annotations,
264
- page,
282
+ generatedAnnotations: annotationKeys,
283
+ page: testGenPage,
265
284
  llm,
266
285
  trace: triggerHintsFlowSpan,
267
286
  });
@@ -1,6 +1,6 @@
1
1
  import { LLM, TraceClient } from "@empiricalrun/llm";
2
2
  import OpenAI from "openai";
3
- import { Page } from "playwright";
3
+ import { TestGenPage } from "../../page";
4
4
  import { BrowsingAgentOptions } from "../browsing";
5
5
  export declare const getUserMessageWithForHints: ({ userMessage, options, pageScreenshot, annotatedPageScreenshot, }: {
6
6
  userMessage: OpenAI.ChatCompletionUserMessageParam;
@@ -14,7 +14,7 @@ export declare const triggerHintsFlow: ({ outputFromGetNextAction, generatedAnno
14
14
  elementAnnotation?: string;
15
15
  };
16
16
  generatedAnnotations: Record<string, any>;
17
- page: Page;
17
+ page: TestGenPage;
18
18
  llm: LLM;
19
19
  trace?: TraceClient | undefined;
20
20
  }) => Promise<{
@@ -1 +1 @@
1
- {"version":3,"file":"with-hints.d.ts","sourceRoot":"","sources":["../../../src/agent/master/with-hints.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAIlC,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,eAAO,MAAM,0BAA0B;iBAMxB,OAAO,8BAA8B;;oBAElC,MAAM;6BACG,MAAM;MAC7B,MAAM,GAAG,OAAO,yBAAyB,EAiC5C,CAAC;AAEF,eAAO,MAAM,gBAAgB;6BAOF;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B;0BACqB,OAAO,MAAM,EAAE,GAAG,CAAC;UACnC,IAAI;SACL,GAAG;;MAEN,QAAQ;IACV,sBAAsB,EAAE,OAAO,CAAC;IAChC,wBAAwB,EAAE,OAAO,qBAAqB,GAAG,SAAS,CAAC;CACpE,CAqGA,CAAC"}
1
+ {"version":3,"file":"with-hints.d.ts","sourceRoot":"","sources":["../../../src/agent/master/with-hints.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,MAAM,MAAM,QAAQ,CAAC;AAI5B,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,eAAO,MAAM,0BAA0B;iBAMxB,OAAO,8BAA8B;;oBAElC,MAAM;6BACG,MAAM;MAC7B,MAAM,GAAG,OAAO,yBAAyB,EAiC5C,CAAC;AAEF,eAAO,MAAM,gBAAgB;6BAOF;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B;0BACqB,OAAO,MAAM,EAAE,GAAG,CAAC;UACnC,WAAW;SACZ,GAAG;;MAEN,QAAQ;IACV,sBAAsB,EAAE,OAAO,CAAC;IAChC,wBAAwB,EAAE,OAAO,qBAAqB,GAAG,SAAS,CAAC;CACpE,CAuGA,CAAC"}
@@ -37,12 +37,12 @@ const triggerHintsFlow = async ({ outputFromGetNextAction, generatedAnnotations,
37
37
  try {
38
38
  const hasElementAnnotation = outputFromGetNextAction?.elementAnnotation?.length &&
39
39
  outputFromGetNextAction?.elementAnnotation?.trim()?.length &&
40
- outputFromGetNextAction?.elementAnnotation in
41
- (generatedAnnotations || {});
40
+ generatedAnnotations?.includes(outputFromGetNextAction?.elementAnnotation);
42
41
  trace?.event({
43
42
  name: "has-element-annotation",
44
43
  output: {
45
44
  hasElementAnnotation,
45
+ generatedAnnotations,
46
46
  },
47
47
  });
48
48
  if (!hasElementAnnotation) {
@@ -0,0 +1,20 @@
1
+ import { TraceClient } from "@empiricalrun/llm";
2
+ /**
3
+ * This agent is used to divide the tasl into individual actions and then
4
+ * compare each action against the actions listed in the conversation.
5
+ * If the task is not fully completed, identify which specific actions are missing and suggest next steps to complete the task.
6
+ *
7
+ * This is very initial stage planner and needs iteration and currently forked from verification agent
8
+ */
9
+ export declare function runtimePlanner({ trace, task, conversation, pages, currentPage, }: {
10
+ trace?: TraceClient;
11
+ conversation: string[];
12
+ task: string;
13
+ pages?: Record<string, any>;
14
+ currentPage?: string;
15
+ }): Promise<{
16
+ pageName: string;
17
+ isDone: boolean;
18
+ reason: string;
19
+ }>;
20
+ //# sourceMappingURL=run-time-planner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-time-planner.d.ts","sourceRoot":"","sources":["../../../src/agent/planner/run-time-planner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,EACnC,KAAK,EACL,IAAI,EACJ,YAAY,EACZ,KAAK,EACL,WAAW,GACZ,EAAE;IACD,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;;;;GA6GA"}
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runtimePlanner = void 0;
4
+ const llm_1 = require("@empiricalrun/llm");
5
+ /**
6
+ * This agent is used to divide the tasl into individual actions and then
7
+ * compare each action against the actions listed in the conversation.
8
+ * If the task is not fully completed, identify which specific actions are missing and suggest next steps to complete the task.
9
+ *
10
+ * This is very initial stage planner and needs iteration and currently forked from verification agent
11
+ */
12
+ async function runtimePlanner({ trace, task, conversation, pages, currentPage, }) {
13
+ const runTimePlannerSpan = trace?.span({
14
+ name: "runtime-planner",
15
+ input: {
16
+ task,
17
+ conversation,
18
+ },
19
+ });
20
+ const llm = new llm_1.LLM({ provider: "openai" });
21
+ const prompt = [
22
+ {
23
+ role: "system",
24
+ content: `
25
+ Given a conversation that lists only the actions that were successfully executed and a task comprising multiple actions, your goal is to analyse the conversation and determine if the entire task is completed.
26
+ These conversations are between AI agents using Playwright to execute actions on browser. These agents already have access to browser tabs to execute steps. The successfully executed steps on browser post browser has opened, is provided to you as conversation.
27
+
28
+ If the task is not fully completed, identify which specific actions are missing and suggest next steps to complete the task. Assume that the conversation provided is entirely truthful and no additional actions were performed beyond those listed.
29
+
30
+ To fulfil your goal, follow these steps:
31
+ - Divide the task into individual actions.
32
+ - Compare each task action against the actions listed in the conversation.
33
+ - Identify which actions have been executed and which have not.
34
+ - If all actions are executed, respond with the task as done.
35
+ - If any actions are missing, respond with the task as not done, listing all actions and specifying which are complete and which are missing.
36
+ - If provided with list of pages, based on the next pending action and previously executed action, identify the page on which next action needs to be taken
37
+ `,
38
+ },
39
+ {
40
+ role: "user",
41
+ content: `
42
+ Task: ${task}
43
+
44
+ Conversation:
45
+ ${conversation.join("\n")}
46
+
47
+ Current page:
48
+ ${currentPage}
49
+ `,
50
+ },
51
+ ];
52
+ const response = await llm.createChatCompletion({
53
+ trace: runTimePlannerSpan,
54
+ traceName: "runtime-planner-llm",
55
+ model: "gpt-4o",
56
+ messages: prompt,
57
+ tools: [
58
+ {
59
+ type: "function",
60
+ function: {
61
+ name: "task_done",
62
+ description: "end the task by calling this method",
63
+ parameters: {
64
+ type: "object",
65
+ properties: {
66
+ actions: {
67
+ type: "string",
68
+ description: "actions extracted from task",
69
+ },
70
+ successful_actions: {
71
+ type: "string",
72
+ description: "successful actions mentioned in the conversation",
73
+ },
74
+ reason: {
75
+ type: "string",
76
+ description: "reasoning for identification of task status",
77
+ },
78
+ isDone: {
79
+ type: "boolean",
80
+ description: "whether the task is done",
81
+ },
82
+ pageName: {
83
+ type: "string",
84
+ enum: pages ? Object.keys(pages) : [],
85
+ description: "page name for the next action.",
86
+ },
87
+ },
88
+ required: ["isDone", "reason", "pageName"],
89
+ },
90
+ },
91
+ },
92
+ ],
93
+ modelParameters: {
94
+ tool_choice: "required",
95
+ temperature: 0.5,
96
+ },
97
+ });
98
+ const toolCallResp = (response?.tool_calls || [])[0];
99
+ if (toolCallResp) {
100
+ const toolCall = JSON.parse(toolCallResp.function.arguments);
101
+ const output = {
102
+ pageName: toolCall.pageName,
103
+ isDone: toolCall.isDone,
104
+ reason: toolCall.reason,
105
+ };
106
+ runTimePlannerSpan?.end({
107
+ output,
108
+ });
109
+ return output;
110
+ }
111
+ const output = {
112
+ pageName: "",
113
+ isDone: false,
114
+ reason: "LLM failed to generate a valid response",
115
+ };
116
+ runTimePlannerSpan?.end({
117
+ output,
118
+ });
119
+ return output;
120
+ }
121
+ exports.runtimePlanner = runtimePlanner;
@@ -1,5 +1,5 @@
1
1
  export declare function createGitIgnoreFileFilter(): Promise<(pathname: string) => boolean>;
2
- export declare function contextForGeneration(file: string): Promise<{
2
+ export declare function contextForGeneration(file?: string): Promise<{
3
3
  codePrompt: string | undefined;
4
4
  pomPrompt: string | undefined;
5
5
  testFileContent: string;
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/bin/utils/context.ts"],"names":[],"mappings":"AAKA,wBAAsB,yBAAyB,2CAS9C;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM;;;;GAOtD;AAED,wBAAsB,iBAAiB,oBAYtC"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/bin/utils/context.ts"],"names":[],"mappings":"AAKA,wBAAsB,yBAAyB,2CAS9C;AAED,wBAAsB,oBAAoB,CAAC,IAAI,CAAC,EAAE,MAAM;;;;GAOvD;AAED,wBAAsB,iBAAiB,oBAYtC"}
@@ -23,7 +23,7 @@ async function contextForGeneration(file) {
23
23
  return {
24
24
  codePrompt: await (0, fs_1.generatePromptFromDirectory)("./tests", filter),
25
25
  pomPrompt: await (0, fs_1.generatePromptFromDirectory)("./pages", filter),
26
- testFileContent: await fs_extra_1.default.readFile(file, "utf-8"),
26
+ testFileContent: file ? await fs_extra_1.default.readFile(file, "utf-8") : "",
27
27
  };
28
28
  }
29
29
  exports.contextForGeneration = contextForGeneration;
@@ -72,4 +72,5 @@ export declare function buildTestNamePrompt({ testName, suites, }: {
72
72
  testName: string;
73
73
  suites: string[];
74
74
  }): string;
75
+ export declare function getVariableDeclarationsFromCode(sourceCode: string): string[];
75
76
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/bin/utils/platform/web/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAGL,IAAI,EAEJ,UAAU,EAEX,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,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,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,+BAoBvE;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;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,iBAsDA;AAED,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EAAE,iBA2BzB;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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/bin/utils/platform/web/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAGL,IAAI,EAEJ,UAAU,EAEX,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,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,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,+BAoBvE;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;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,iBAsDA;AAED,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EAAE,iBA2BzB;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"}
@@ -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.buildTestNamePrompt = exports.isTestPresent = exports.appendScopeToCreateTest = exports.addUserContextFixture = exports.importAllExportsStmtFromFilePaths = 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 = exports.getTestModuleAliasFromSourceFile = void 0;
6
+ exports.getVariableDeclarationsFromCode = exports.buildTestNamePrompt = exports.isTestPresent = exports.appendScopeToCreateTest = exports.addUserContextFixture = exports.importAllExportsStmtFromFilePaths = 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 = exports.getTestModuleAliasFromSourceFile = void 0;
7
7
  const eslint_1 = require("eslint");
8
8
  const fs_1 = require("fs");
9
9
  const fs_extra_1 = __importDefault(require("fs-extra"));
@@ -474,3 +474,29 @@ function buildTestNamePrompt({ testName, suites, }) {
474
474
  : testName;
475
475
  }
476
476
  exports.buildTestNamePrompt = buildTestNamePrompt;
477
+ function getVariableDeclarationsFromCode(sourceCode) {
478
+ const project = new ts_morph_1.Project();
479
+ const sourceFile = project.createSourceFile("temp.ts", sourceCode);
480
+ // Extract variable declarations
481
+ const variables = sourceFile.getDescendantsOfKind(ts_morph_1.SyntaxKind.VariableDeclaration);
482
+ // Function to extract individual variables from destructured declarations
483
+ function extractVariables(variable) {
484
+ const nameNode = variable.getNameNode();
485
+ if (nameNode.getKind() === ts_morph_1.SyntaxKind.ObjectBindingPattern) {
486
+ // For object destructuring
487
+ return nameNode.getElements().map((element) => element.getName());
488
+ }
489
+ else if (nameNode.getKind() === ts_morph_1.SyntaxKind.ArrayBindingPattern) {
490
+ // For array destructuring
491
+ return nameNode.getElements().map((element) => element.getText());
492
+ }
493
+ else {
494
+ // For regular variable declarations
495
+ return [variable.getName()];
496
+ }
497
+ }
498
+ // Collect all variable names
499
+ const allVariables = variables.flatMap((variable) => extractVariables(variable));
500
+ return allVariables;
501
+ }
502
+ exports.getVariableDeclarationsFromCode = getVariableDeclarationsFromCode;