@empiricalrun/playwright-utils 0.22.7 → 0.23.0

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 (274) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/bundled/test-gen/actions/assert.d.ts +4 -0
  3. package/bundled/test-gen/actions/assert.d.ts.map +1 -0
  4. package/bundled/test-gen/actions/assert.js +50 -0
  5. package/bundled/test-gen/actions/click.d.ts +4 -0
  6. package/bundled/test-gen/actions/click.d.ts.map +1 -0
  7. package/bundled/test-gen/actions/click.js +51 -0
  8. package/bundled/test-gen/actions/constants/index.d.ts +2 -0
  9. package/bundled/test-gen/actions/constants/index.d.ts.map +1 -0
  10. package/bundled/test-gen/actions/constants/index.js +4 -0
  11. package/bundled/test-gen/actions/done.d.ts +4 -0
  12. package/bundled/test-gen/actions/done.d.ts.map +1 -0
  13. package/bundled/test-gen/actions/done.js +30 -0
  14. package/bundled/test-gen/actions/fill.d.ts +4 -0
  15. package/bundled/test-gen/actions/fill.d.ts.map +1 -0
  16. package/bundled/test-gen/actions/fill.js +82 -0
  17. package/bundled/test-gen/actions/goto.d.ts +4 -0
  18. package/bundled/test-gen/actions/goto.d.ts.map +1 -0
  19. package/bundled/test-gen/actions/goto.js +47 -0
  20. package/bundled/test-gen/actions/hover.d.ts +4 -0
  21. package/bundled/test-gen/actions/hover.d.ts.map +1 -0
  22. package/bundled/test-gen/actions/hover.js +51 -0
  23. package/bundled/test-gen/actions/index.d.ts +30 -0
  24. package/bundled/test-gen/actions/index.d.ts.map +1 -0
  25. package/bundled/test-gen/actions/index.js +159 -0
  26. package/bundled/test-gen/actions/next-task.d.ts +53 -0
  27. package/bundled/test-gen/actions/next-task.d.ts.map +1 -0
  28. package/bundled/test-gen/actions/next-task.js +58 -0
  29. package/bundled/test-gen/actions/press.d.ts +4 -0
  30. package/bundled/test-gen/actions/press.d.ts.map +1 -0
  31. package/bundled/test-gen/actions/press.js +56 -0
  32. package/bundled/test-gen/actions/skill.d.ts +21 -0
  33. package/bundled/test-gen/actions/skill.d.ts.map +1 -0
  34. package/bundled/test-gen/actions/skill.js +127 -0
  35. package/bundled/test-gen/actions/text-content.d.ts +4 -0
  36. package/bundled/test-gen/actions/text-content.d.ts.map +1 -0
  37. package/bundled/test-gen/actions/text-content.js +58 -0
  38. package/bundled/test-gen/actions/utils/index.d.ts +10 -0
  39. package/bundled/test-gen/actions/utils/index.d.ts.map +1 -0
  40. package/bundled/test-gen/actions/utils/index.js +109 -0
  41. package/bundled/test-gen/agent/browsing/index.d.ts +15 -0
  42. package/bundled/test-gen/agent/browsing/index.d.ts.map +1 -0
  43. package/bundled/test-gen/agent/browsing/index.js +68 -0
  44. package/bundled/test-gen/agent/browsing/run.d.ts +19 -0
  45. package/bundled/test-gen/agent/browsing/run.d.ts.map +1 -0
  46. package/bundled/test-gen/agent/browsing/run.js +88 -0
  47. package/bundled/test-gen/agent/browsing/utils.d.ts +41 -0
  48. package/bundled/test-gen/agent/browsing/utils.d.ts.map +1 -0
  49. package/bundled/test-gen/agent/browsing/utils.js +406 -0
  50. package/bundled/test-gen/agent/codegen/create-test-block.d.ts +9 -0
  51. package/bundled/test-gen/agent/codegen/create-test-block.d.ts.map +1 -0
  52. package/bundled/test-gen/agent/codegen/create-test-block.js +63 -0
  53. package/bundled/test-gen/agent/codegen/fix-ts-errors.d.ts +13 -0
  54. package/bundled/test-gen/agent/codegen/fix-ts-errors.d.ts.map +1 -0
  55. package/bundled/test-gen/agent/codegen/fix-ts-errors.js +80 -0
  56. package/bundled/test-gen/agent/codegen/generate-code-apply-changes.d.ts +13 -0
  57. package/bundled/test-gen/agent/codegen/generate-code-apply-changes.d.ts.map +1 -0
  58. package/bundled/test-gen/agent/codegen/generate-code-apply-changes.js +381 -0
  59. package/bundled/test-gen/agent/codegen/lexical-scoped-vars.d.ts +9 -0
  60. package/bundled/test-gen/agent/codegen/lexical-scoped-vars.d.ts.map +1 -0
  61. package/bundled/test-gen/agent/codegen/lexical-scoped-vars.js +56 -0
  62. package/bundled/test-gen/agent/codegen/repo-edit.d.ts +23 -0
  63. package/bundled/test-gen/agent/codegen/repo-edit.d.ts.map +1 -0
  64. package/bundled/test-gen/agent/codegen/repo-edit.js +86 -0
  65. package/bundled/test-gen/agent/codegen/run.d.ts +16 -0
  66. package/bundled/test-gen/agent/codegen/run.d.ts.map +1 -0
  67. package/bundled/test-gen/agent/codegen/run.js +119 -0
  68. package/bundled/test-gen/agent/codegen/skills-retriever.d.ts +26 -0
  69. package/bundled/test-gen/agent/codegen/skills-retriever.d.ts.map +1 -0
  70. package/bundled/test-gen/agent/codegen/skills-retriever.js +93 -0
  71. package/bundled/test-gen/agent/codegen/test-update-feedback.d.ts +12 -0
  72. package/bundled/test-gen/agent/codegen/test-update-feedback.d.ts.map +1 -0
  73. package/bundled/test-gen/agent/codegen/test-update-feedback.js +50 -0
  74. package/bundled/test-gen/agent/codegen/types.d.ts +25 -0
  75. package/bundled/test-gen/agent/codegen/types.d.ts.map +1 -0
  76. package/bundled/test-gen/agent/codegen/types.js +8 -0
  77. package/bundled/test-gen/agent/codegen/update-flow.d.ts +34 -0
  78. package/bundled/test-gen/agent/codegen/update-flow.d.ts.map +1 -0
  79. package/bundled/test-gen/agent/codegen/update-flow.js +300 -0
  80. package/bundled/test-gen/agent/codegen/use-skill.d.ts +11 -0
  81. package/bundled/test-gen/agent/codegen/use-skill.d.ts.map +1 -0
  82. package/bundled/test-gen/agent/codegen/use-skill.js +54 -0
  83. package/bundled/test-gen/agent/codegen/utils.d.ts +126 -0
  84. package/bundled/test-gen/agent/codegen/utils.d.ts.map +1 -0
  85. package/bundled/test-gen/agent/codegen/utils.js +416 -0
  86. package/bundled/test-gen/agent/diagnosis-agent/index.d.ts +18 -0
  87. package/bundled/test-gen/agent/diagnosis-agent/index.d.ts.map +1 -0
  88. package/bundled/test-gen/agent/diagnosis-agent/index.js +105 -0
  89. package/bundled/test-gen/agent/diagnosis-agent/strict-mode-violation.d.ts +9 -0
  90. package/bundled/test-gen/agent/diagnosis-agent/strict-mode-violation.d.ts.map +1 -0
  91. package/bundled/test-gen/agent/diagnosis-agent/strict-mode-violation.js +31 -0
  92. package/bundled/test-gen/agent/enrich-prompt/index.d.ts +12 -0
  93. package/bundled/test-gen/agent/enrich-prompt/index.d.ts.map +1 -0
  94. package/bundled/test-gen/agent/enrich-prompt/index.js +81 -0
  95. package/bundled/test-gen/agent/enrich-prompt/utils.d.ts +6 -0
  96. package/bundled/test-gen/agent/enrich-prompt/utils.d.ts.map +1 -0
  97. package/bundled/test-gen/agent/enrich-prompt/utils.js +12 -0
  98. package/bundled/test-gen/agent/infer-agent/index.d.ts +10 -0
  99. package/bundled/test-gen/agent/infer-agent/index.d.ts.map +1 -0
  100. package/bundled/test-gen/agent/infer-agent/index.js +70 -0
  101. package/bundled/test-gen/agent/master/action-tool-calls.d.ts +42 -0
  102. package/bundled/test-gen/agent/master/action-tool-calls.d.ts.map +1 -0
  103. package/bundled/test-gen/agent/master/action-tool-calls.js +87 -0
  104. package/bundled/test-gen/agent/master/browser-tests/fixtures.d.ts +9 -0
  105. package/bundled/test-gen/agent/master/browser-tests/fixtures.d.ts.map +1 -0
  106. package/bundled/test-gen/agent/master/browser-tests/fixtures.js +33 -0
  107. package/bundled/test-gen/agent/master/browser-tests/index.spec.d.ts +2 -0
  108. package/bundled/test-gen/agent/master/browser-tests/index.spec.d.ts.map +1 -0
  109. package/bundled/test-gen/agent/master/browser-tests/index.spec.js +113 -0
  110. package/bundled/test-gen/agent/master/browser-tests/skills.spec.d.ts +2 -0
  111. package/bundled/test-gen/agent/master/browser-tests/skills.spec.d.ts.map +1 -0
  112. package/bundled/test-gen/agent/master/browser-tests/skills.spec.js +109 -0
  113. package/bundled/test-gen/agent/master/element-annotation.d.ts +30 -0
  114. package/bundled/test-gen/agent/master/element-annotation.d.ts.map +1 -0
  115. package/bundled/test-gen/agent/master/element-annotation.js +195 -0
  116. package/bundled/test-gen/agent/master/execute-browser-action.d.ts +24 -0
  117. package/bundled/test-gen/agent/master/execute-browser-action.d.ts.map +1 -0
  118. package/bundled/test-gen/agent/master/execute-browser-action.js +124 -0
  119. package/bundled/test-gen/agent/master/execute-skill-action.d.ts +11 -0
  120. package/bundled/test-gen/agent/master/execute-skill-action.d.ts.map +1 -0
  121. package/bundled/test-gen/agent/master/execute-skill-action.js +25 -0
  122. package/bundled/test-gen/agent/master/icon-descriptor/index.d.ts +22 -0
  123. package/bundled/test-gen/agent/master/icon-descriptor/index.d.ts.map +1 -0
  124. package/bundled/test-gen/agent/master/icon-descriptor/index.js +250 -0
  125. package/bundled/test-gen/agent/master/icon-descriptor/normalize-svg.d.ts +2 -0
  126. package/bundled/test-gen/agent/master/icon-descriptor/normalize-svg.d.ts.map +1 -0
  127. package/bundled/test-gen/agent/master/icon-descriptor/normalize-svg.js +248 -0
  128. package/bundled/test-gen/agent/master/next-action.d.ts +22 -0
  129. package/bundled/test-gen/agent/master/next-action.d.ts.map +1 -0
  130. package/bundled/test-gen/agent/master/next-action.js +104 -0
  131. package/bundled/test-gen/agent/master/planner.d.ts +15 -0
  132. package/bundled/test-gen/agent/master/planner.d.ts.map +1 -0
  133. package/bundled/test-gen/agent/master/planner.js +144 -0
  134. package/bundled/test-gen/agent/master/run.d.ts +15 -0
  135. package/bundled/test-gen/agent/master/run.d.ts.map +1 -0
  136. package/bundled/test-gen/agent/master/run.js +274 -0
  137. package/bundled/test-gen/agent/master/scroller.d.ts +15 -0
  138. package/bundled/test-gen/agent/master/scroller.d.ts.map +1 -0
  139. package/bundled/test-gen/agent/master/scroller.js +375 -0
  140. package/bundled/test-gen/agent/master/with-hints.d.ts +17 -0
  141. package/bundled/test-gen/agent/master/with-hints.d.ts.map +1 -0
  142. package/bundled/test-gen/agent/master/with-hints.js +102 -0
  143. package/bundled/test-gen/agent/planner/run-time-planner.d.ts +15 -0
  144. package/bundled/test-gen/agent/planner/run-time-planner.d.ts.map +1 -0
  145. package/bundled/test-gen/agent/planner/run-time-planner.js +100 -0
  146. package/bundled/test-gen/agent/planner/run.d.ts +7 -0
  147. package/bundled/test-gen/agent/planner/run.d.ts.map +1 -0
  148. package/bundled/test-gen/agent/planner/run.js +127 -0
  149. package/bundled/test-gen/agent/utils.d.ts +2 -0
  150. package/bundled/test-gen/agent/utils.d.ts.map +1 -0
  151. package/bundled/test-gen/agent/utils.js +12 -0
  152. package/bundled/test-gen/bin/index.d.ts +3 -0
  153. package/bundled/test-gen/bin/index.d.ts.map +1 -0
  154. package/bundled/test-gen/bin/index.js +212 -0
  155. package/bundled/test-gen/bin/logger/index.d.ts +14 -0
  156. package/bundled/test-gen/bin/logger/index.d.ts.map +1 -0
  157. package/bundled/test-gen/bin/logger/index.js +57 -0
  158. package/bundled/test-gen/bin/utils/context.d.ts +13 -0
  159. package/bundled/test-gen/bin/utils/context.d.ts.map +1 -0
  160. package/bundled/test-gen/bin/utils/context.js +67 -0
  161. package/bundled/test-gen/bin/utils/fs/index.d.ts +6 -0
  162. package/bundled/test-gen/bin/utils/fs/index.d.ts.map +1 -0
  163. package/bundled/test-gen/bin/utils/fs/index.js +63 -0
  164. package/bundled/test-gen/bin/utils/index.d.ts +9 -0
  165. package/bundled/test-gen/bin/utils/index.d.ts.map +1 -0
  166. package/bundled/test-gen/bin/utils/index.js +64 -0
  167. package/bundled/test-gen/bin/utils/platform/web/index.d.ts +78 -0
  168. package/bundled/test-gen/bin/utils/platform/web/index.d.ts.map +1 -0
  169. package/bundled/test-gen/bin/utils/platform/web/index.js +544 -0
  170. package/bundled/test-gen/bin/utils/platform/web/test-files/ts-path-import-validate.d.ts +2 -0
  171. package/bundled/test-gen/bin/utils/platform/web/test-files/ts-path-import-validate.d.ts.map +1 -0
  172. package/bundled/test-gen/bin/utils/platform/web/test-files/ts-path-import-validate.js +7 -0
  173. package/bundled/test-gen/bin/utils/scenarios/index.d.ts +6 -0
  174. package/bundled/test-gen/bin/utils/scenarios/index.d.ts.map +1 -0
  175. package/bundled/test-gen/bin/utils/scenarios/index.js +57 -0
  176. package/bundled/test-gen/browser-injected-scripts/annotate-elements.js +615 -0
  177. package/bundled/test-gen/browser-injected-scripts/annotate-elements.spec.d.ts +2 -0
  178. package/bundled/test-gen/browser-injected-scripts/annotate-elements.spec.d.ts.map +1 -0
  179. package/bundled/test-gen/browser-injected-scripts/annotate-elements.spec.js +207 -0
  180. package/bundled/test-gen/browser-injected-scripts/annotate-elements.spec.ts +332 -0
  181. package/bundled/test-gen/constants/index.d.ts +7 -0
  182. package/bundled/test-gen/constants/index.d.ts.map +1 -0
  183. package/bundled/test-gen/constants/index.js +18 -0
  184. package/bundled/test-gen/errors/index.d.ts +5 -0
  185. package/bundled/test-gen/errors/index.d.ts.map +1 -0
  186. package/bundled/test-gen/errors/index.js +9 -0
  187. package/bundled/test-gen/evals/add-scenario-agent.evals.d.ts +4 -0
  188. package/bundled/test-gen/evals/add-scenario-agent.evals.d.ts.map +1 -0
  189. package/bundled/test-gen/evals/add-scenario-agent.evals.js +44 -0
  190. package/bundled/test-gen/evals/append-create-test-agent.evals.d.ts +4 -0
  191. package/bundled/test-gen/evals/append-create-test-agent.evals.d.ts.map +1 -0
  192. package/bundled/test-gen/evals/append-create-test-agent.evals.js +117 -0
  193. package/bundled/test-gen/evals/fetch-pom-skills-agent.evals.d.ts +4 -0
  194. package/bundled/test-gen/evals/fetch-pom-skills-agent.evals.d.ts.map +1 -0
  195. package/bundled/test-gen/evals/fetch-pom-skills-agent.evals.js +36 -0
  196. package/bundled/test-gen/evals/infer-master-or-code-agent.evals.d.ts +4 -0
  197. package/bundled/test-gen/evals/infer-master-or-code-agent.evals.d.ts.map +1 -0
  198. package/bundled/test-gen/evals/infer-master-or-code-agent.evals.js +22 -0
  199. package/bundled/test-gen/evals/master-agent.evals.d.ts +4 -0
  200. package/bundled/test-gen/evals/master-agent.evals.d.ts.map +1 -0
  201. package/bundled/test-gen/evals/master-agent.evals.js +35 -0
  202. package/bundled/test-gen/evals/type.d.ts +12 -0
  203. package/bundled/test-gen/evals/type.d.ts.map +1 -0
  204. package/bundled/test-gen/evals/type.js +2 -0
  205. package/bundled/test-gen/evals/update-scenario-agent.evals.d.ts +4 -0
  206. package/bundled/test-gen/evals/update-scenario-agent.evals.d.ts.map +1 -0
  207. package/bundled/test-gen/evals/update-scenario-agent.evals.js +47 -0
  208. package/bundled/test-gen/file/client.d.ts +14 -0
  209. package/bundled/test-gen/file/client.d.ts.map +1 -0
  210. package/bundled/test-gen/file/client.js +48 -0
  211. package/bundled/test-gen/file/server.d.ts +13 -0
  212. package/bundled/test-gen/file/server.d.ts.map +1 -0
  213. package/bundled/test-gen/file/server.js +52 -0
  214. package/bundled/test-gen/human-in-the-loop/cli.d.ts +2 -0
  215. package/bundled/test-gen/human-in-the-loop/cli.d.ts.map +1 -0
  216. package/bundled/test-gen/human-in-the-loop/cli.js +24 -0
  217. package/bundled/test-gen/human-in-the-loop/index.d.ts +12 -0
  218. package/bundled/test-gen/human-in-the-loop/index.d.ts.map +1 -0
  219. package/bundled/test-gen/human-in-the-loop/index.js +30 -0
  220. package/bundled/test-gen/human-in-the-loop/ipc.d.ts +4 -0
  221. package/bundled/test-gen/human-in-the-loop/ipc.d.ts.map +1 -0
  222. package/bundled/test-gen/human-in-the-loop/ipc.js +47 -0
  223. package/bundled/test-gen/index.d.ts +4 -0
  224. package/bundled/test-gen/index.d.ts.map +1 -0
  225. package/bundled/test-gen/index.js +55 -0
  226. package/bundled/test-gen/package.json +106 -0
  227. package/bundled/test-gen/page/index.d.ts +11 -0
  228. package/bundled/test-gen/page/index.d.ts.map +1 -0
  229. package/bundled/test-gen/page/index.js +16 -0
  230. package/bundled/test-gen/prompts/lib/ts-transformer.d.ts +4 -0
  231. package/bundled/test-gen/prompts/lib/ts-transformer.d.ts.map +1 -0
  232. package/bundled/test-gen/prompts/lib/ts-transformer.js +92 -0
  233. package/bundled/test-gen/reporter/index.d.ts +33 -0
  234. package/bundled/test-gen/reporter/index.d.ts.map +1 -0
  235. package/bundled/test-gen/reporter/index.js +161 -0
  236. package/bundled/test-gen/session/index.d.ts +20 -0
  237. package/bundled/test-gen/session/index.d.ts.map +1 -0
  238. package/bundled/test-gen/session/index.js +105 -0
  239. package/bundled/test-gen/test-build/index.d.ts +10 -0
  240. package/bundled/test-gen/test-build/index.d.ts.map +1 -0
  241. package/bundled/test-gen/test-build/index.js +30 -0
  242. package/bundled/test-gen/types/index.d.ts +69 -0
  243. package/bundled/test-gen/types/index.d.ts.map +1 -0
  244. package/bundled/test-gen/types/index.js +2 -0
  245. package/bundled/test-gen/uploader/index.d.ts +26 -0
  246. package/bundled/test-gen/uploader/index.d.ts.map +1 -0
  247. package/bundled/test-gen/uploader/index.js +102 -0
  248. package/bundled/test-gen/utils/env.d.ts +2 -0
  249. package/bundled/test-gen/utils/env.d.ts.map +1 -0
  250. package/bundled/test-gen/utils/env.js +9 -0
  251. package/bundled/test-gen/utils/exec.d.ts +4 -0
  252. package/bundled/test-gen/utils/exec.d.ts.map +1 -0
  253. package/bundled/test-gen/utils/exec.js +45 -0
  254. package/bundled/test-gen/utils/file.d.ts +2 -0
  255. package/bundled/test-gen/utils/file.d.ts.map +1 -0
  256. package/bundled/test-gen/utils/file.js +25 -0
  257. package/bundled/test-gen/utils/html.d.ts +4 -0
  258. package/bundled/test-gen/utils/html.d.ts.map +1 -0
  259. package/bundled/test-gen/utils/html.js +46 -0
  260. package/bundled/test-gen/utils/index.d.ts +2 -0
  261. package/bundled/test-gen/utils/index.d.ts.map +1 -0
  262. package/bundled/test-gen/utils/index.js +5 -0
  263. package/bundled/test-gen/utils/pw-test.d.ts +3 -0
  264. package/bundled/test-gen/utils/pw-test.d.ts.map +1 -0
  265. package/bundled/test-gen/utils/pw-test.js +26 -0
  266. package/bundled/test-gen/utils/slug.d.ts +2 -0
  267. package/bundled/test-gen/utils/slug.d.ts.map +1 -0
  268. package/bundled/test-gen/utils/slug.js +18 -0
  269. package/bundled/test-gen/utils/string.d.ts +2 -0
  270. package/bundled/test-gen/utils/string.d.ts.map +1 -0
  271. package/bundled/test-gen/utils/string.js +9 -0
  272. package/dist/overlay-tests/click.spec.js +1 -1
  273. package/package.json +3 -3
  274. package/scripts/prepare-publish.js +42 -0
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.enrichPromptWithFailingLine = void 0;
4
+ const llm_1 = require("@empiricalrun/llm");
5
+ const constants_1 = require("../../constants");
6
+ const promptTemplate_0 = "{{#section \"system\"}}\nYou are a software QA engineer who is asked to update an automated browser test written that failed during a test run.\n\nYou will be provided with the details of the failure and then a user prompt that details what needs to be changed.\n\n# Details of the failure\n### Failing line:\n{{testBlock}}\n\n### Failing test file path:\n{{testFilePath}}\n\nYour goal is to enrich the user message with \"Failing line\" and \"Failing test file path\", if the user's message contains\nrequests like correcting or replacing failing lines or statements.\n\nTo fulfil your goal, follow these steps:\n1. Identify the user intent and check if the user says anything similar to:\n- \"Replace the failing line\"\n- \"Replace the error statement\"\n- \"Replace the failing statement\"\n- \"Replace the failed user action\"\n2. The user message intent can also be to modify things in or around the \"failing line\". Lookout for this scenario as\nwell to enrich the user message\n3. If such keywords are present, only then enrich the user message by inserting \"Failing line\" and \"Failing test file\npath\" at appropriate locations.\n\nBefore submitting your response, ensure the following:\n- Do not generate code for the user prompt. Your task is just to enrich the user message\n- Enrich the user message ONLY if any of these keywords are present - \"failing line\", \"error statement\", \"failing\nstatement\", \"failed user action\"\n- Do not include any markdown syntax or backticks\n- Respond with <reason_for_output></reason_for_output>, <is_user_message_enriched></is_user_message_enriched> and\n<output></output> as xml tags\n- is_user_message_enriched can be either true or false\n- output should follow the format: \"Replace the line <code> with <whatever is required to be done> in <file_path>\"\n{{/section}}\n\n{{#section \"user\"}}\nUser message:\n{{userMessage}}\n{{/section}}";
7
+ const utils_1 = require("./utils");
8
+ const responseFormat = {
9
+ type: "json_schema",
10
+ json_schema: {
11
+ name: "analyze_user_message_and_conditionally_enrich_it",
12
+ strict: true,
13
+ schema: {
14
+ type: "object",
15
+ properties: {
16
+ reason_for_output: {
17
+ type: "string",
18
+ description: "provide reason in both cases whether the user message was enriched or not",
19
+ },
20
+ is_user_message_enriched: {
21
+ type: "boolean",
22
+ description: "whether the user message should be enriched or not",
23
+ },
24
+ output: {
25
+ type: "string",
26
+ description: "This is the final output after analyzing the user message, and optionally enriching it.",
27
+ },
28
+ },
29
+ required: ["is_user_message_enriched", "output", "reason_for_output"],
30
+ additionalProperties: false,
31
+ },
32
+ },
33
+ };
34
+ const enrichPromptWithFailingLine = async ({ trace, testBlock, testFilePath, suggestionForFix, }) => {
35
+ let output = {
36
+ output: suggestionForFix,
37
+ is_user_message_enriched: false,
38
+ reason_for_output: "",
39
+ };
40
+ try {
41
+ const enrichedPromptSpan = trace?.span({
42
+ name: "enrich-prompt-with-failing-line",
43
+ input: {
44
+ testBlock,
45
+ testFilePath,
46
+ suggestionForFix,
47
+ },
48
+ });
49
+ const instructions = (0, llm_1.compilePrompt)(promptTemplate_0, {
50
+ testBlock,
51
+ testFilePath,
52
+ userMessage: suggestionForFix,
53
+ });
54
+ const llm = new llm_1.LLM({
55
+ trace: enrichedPromptSpan,
56
+ providerApiKey: constants_1.MODEL_API_KEYS["anthropic"],
57
+ provider: "anthropic",
58
+ defaultModel: "claude-3-5-sonnet-latest",
59
+ });
60
+ const llmResponse = await llm.createChatCompletion({
61
+ messages: instructions,
62
+ trace,
63
+ modelParameters: {
64
+ temperature: 0.5,
65
+ },
66
+ responseFormat,
67
+ });
68
+ const generateRequestedChangeResponse = (0, utils_1.extractGenerateRequestedChange)(llmResponse?.content);
69
+ output = {
70
+ output: generateRequestedChangeResponse.output,
71
+ is_user_message_enriched: generateRequestedChangeResponse.is_user_message_enriched,
72
+ reason_for_output: generateRequestedChangeResponse.reason_for_output,
73
+ };
74
+ enrichedPromptSpan?.end({ output: output });
75
+ }
76
+ catch (e) {
77
+ console.error(`Failed to generate requested change for test - "${testBlock}", suggestion - "${suggestionForFix}"`, e);
78
+ }
79
+ return output;
80
+ };
81
+ exports.enrichPromptWithFailingLine = enrichPromptWithFailingLine;
@@ -0,0 +1,6 @@
1
+ export declare function extractGenerateRequestedChange(input: string): {
2
+ reason_for_output: string;
3
+ is_user_message_enriched: boolean;
4
+ output: string;
5
+ };
6
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/agent/enrich-prompt/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,MAAM,GAAG;IAC7D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,wBAAwB,EAAE,OAAO,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;CAChB,CAQA"}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractGenerateRequestedChange = void 0;
4
+ function extractGenerateRequestedChange(input) {
5
+ const regex = /<reason_for_output>([\s\S]*?)<\/reason_for_output>[\s\S]*?<is_user_message_enriched>([\s\S]*?)<\/is_user_message_enriched>[\s\S]*?<output>([\s\S]*?)<\/output>/g;
6
+ const match = regex.exec(input);
7
+ const reason_for_output = match[1]?.trim() || "";
8
+ const is_user_message_enriched = match[2]?.trim() === "true";
9
+ const output = match[3]?.trim() || "";
10
+ return { reason_for_output, is_user_message_enriched, output };
11
+ }
12
+ exports.extractGenerateRequestedChange = extractGenerateRequestedChange;
@@ -0,0 +1,10 @@
1
+ import { TraceClient } from "@empiricalrun/llm";
2
+ import { Agent, TestGenConfigOptions } from "@empiricalrun/shared-types";
3
+ export declare function inferAgentBasedTask({ task, options, trace, }: {
4
+ task: string;
5
+ options?: TestGenConfigOptions;
6
+ trace?: TraceClient;
7
+ }): Promise<{
8
+ response: Agent;
9
+ }>;
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agent/infer-agent/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAYzE,wBAAsB,mBAAmB,CAAC,EACxC,IAAI,EACJ,OAAO,EACP,KAAK,GACN,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,KAAK,CAAA;CAAE,CAAC,CAmE/B"}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.inferAgentBasedTask = void 0;
4
+ const llm_1 = require("@empiricalrun/llm");
5
+ const constants_1 = require("../../constants");
6
+ const promptTemplate_0 = "{{#section \"system\"}}\nYou are a software test engineer specializing in Playwright end-to-end tests. You are given a task which is a part of an\nend-to-end test scenario. The task may involve updating an existing end-to-end test case or writing a new test case from\nscratch. Tests involve user interactions (e.g. click on element) or other actions supported by Playwright (e.g.\nintercept network requests)\n\nYour objective is to identify whether the task requires accessing a web browser or not.\n\nTo fulfill your objective, answer the following questions:\n\n1. Does it require you to interact with a UI element in the browser? Examples of interactions are click, fill, type, key\npress, assert visibility of the element. Actions that interact with network requests are not UI element interactions.\n\n2. Is the locator of this UI element given to you in the task? Locators look like `getByText(...)`, `getByTestId(...)`\nand other locator methods in Playwright\n\n3. Decide if you need a browser: if you need to interact with a UI element AND you are NOT given the locator for that\nelement, you WILL NEED a browser.\n\n4. If you NEED a browser, then respond with answer as \"master\", otherwise respond with \"code\"\n\n\n# Example 1\n## Input\nTask:\nin this test don't delete the agent and remove steps after that\n\n## Output\n- ui_interaction_to_be_performed: There is no interaction here\n- ui_element_to_interact_with: No element specified\n- has_locator_for_that_element: No element specified\n- reasoning_for_browser_required: No interaction hence browser is not required\n- answer: code\n\n# Example 2\n## Input\nTask:\nin the swapfast test, replace the selectTokenForSwap method. Instead we will do this\\nclick on token button - this will\nshow a drawer\\nEnter usd in the search field that shows up in the drawer\\nSelect USDC.axl for Cosmos Hub - very\nimportant to choose this instead of USDC.axl on Osmosis\n\n## Output\n- ui_interaction_to_be_performed: Click on token button\n- ui_element_to_interact_with: Token button\n- has_locator_for_that_element: false\n- reasoning_for_browser_required: Task requires interacting with a UI element and identifying its locator which needs a\nbrowser\n- answer: master\n{{/section}}\n\n{{#section \"user\"}}\nTask:\n{{task}}\n{{/section}}";
7
+ const session_1 = require("../../session");
8
+ const session = (0, session_1.getSessionDetails)();
9
+ async function inferAgentBasedTask({ task, options, trace, }) {
10
+ trace =
11
+ trace ||
12
+ llm_1.langfuseInstance?.trace({
13
+ name: "infer-agent-task",
14
+ id: crypto.randomUUID(),
15
+ release: session.version,
16
+ });
17
+ const inferAgentSpan = trace?.span({
18
+ name: "infer-agent",
19
+ input: {
20
+ task,
21
+ options,
22
+ },
23
+ });
24
+ const messages = (0, llm_1.compilePrompt)(promptTemplate_0, { task });
25
+ const llm = new llm_1.LLM({
26
+ trace: inferAgentSpan,
27
+ provider: options?.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER,
28
+ defaultModel: options?.model || constants_1.DEFAULT_MODEL,
29
+ providerApiKey: constants_1.MODEL_API_KEYS[options?.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER],
30
+ });
31
+ const firstShotMessage = await llm.createChatCompletion({
32
+ messages,
33
+ modelParameters: {
34
+ ...constants_1.DEFAULT_MODEL_PARAMETERS,
35
+ ...options?.modelParameters,
36
+ temperature: 1,
37
+ },
38
+ responseFormat: {
39
+ type: "json_schema",
40
+ json_schema: {
41
+ name: "infer-master-code",
42
+ strict: true,
43
+ schema: {
44
+ type: "object",
45
+ properties: {
46
+ reason: {
47
+ type: "string",
48
+ },
49
+ response: {
50
+ type: "string",
51
+ },
52
+ },
53
+ additionalProperties: false,
54
+ required: ["reason", "response"],
55
+ },
56
+ },
57
+ },
58
+ });
59
+ const output = JSON.parse(firstShotMessage?.content || "{}");
60
+ inferAgentSpan?.end({
61
+ output: {
62
+ response: output.response,
63
+ reason: output.reason,
64
+ },
65
+ });
66
+ return {
67
+ response: output.response,
68
+ };
69
+ }
70
+ exports.inferAgentBasedTask = inferAgentBasedTask;
@@ -0,0 +1,42 @@
1
+ export declare enum ActionType {
2
+ FILL = "fill",
3
+ PAGE_GOTO = "page_goto",
4
+ CLICK = "click",
5
+ PRESS_ACTION = "keyboard_press_on_element",
6
+ ASSERT_TEXT = "assert_text",
7
+ HOVER = "hover_element",
8
+ SCROLL = "scroll",
9
+ OBSERVATION = "observation",
10
+ UNKNOWN = "unknown"
11
+ }
12
+ export declare function isValidActionType(value: string): value is ActionType;
13
+ export declare function getActionToolCalls(): {
14
+ type: string;
15
+ function: {
16
+ name: string;
17
+ description: string;
18
+ parameters: {
19
+ type: string;
20
+ properties: {
21
+ reason: {
22
+ type: string;
23
+ description: string;
24
+ };
25
+ action: {
26
+ type: string;
27
+ description: string;
28
+ };
29
+ element_description: {
30
+ type: string;
31
+ description: string;
32
+ };
33
+ is_element_visible: {
34
+ type: string;
35
+ description: string;
36
+ };
37
+ };
38
+ required: string[];
39
+ };
40
+ };
41
+ }[];
42
+ //# sourceMappingURL=action-tool-calls.d.ts.map
@@ -0,0 +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;IACjB,WAAW,gBAAgB;IAC3B,OAAO,YAAY;CACpB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,UAAU,CAEpE;AAqDD,wBAAgB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA8CjC"}
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getActionToolCalls = exports.isValidActionType = exports.ActionType = void 0;
4
+ var ActionType;
5
+ (function (ActionType) {
6
+ ActionType["FILL"] = "fill";
7
+ ActionType["PAGE_GOTO"] = "page_goto";
8
+ ActionType["CLICK"] = "click";
9
+ ActionType["PRESS_ACTION"] = "keyboard_press_on_element";
10
+ ActionType["ASSERT_TEXT"] = "assert_text";
11
+ ActionType["HOVER"] = "hover_element";
12
+ ActionType["SCROLL"] = "scroll";
13
+ ActionType["OBSERVATION"] = "observation";
14
+ ActionType["UNKNOWN"] = "unknown";
15
+ })(ActionType || (exports.ActionType = ActionType = {}));
16
+ function isValidActionType(value) {
17
+ return Object.values(ActionType).includes(value);
18
+ }
19
+ exports.isValidActionType = isValidActionType;
20
+ const createActionCall = (name, description, additionalProperties = {}) => ({
21
+ type: "function",
22
+ function: {
23
+ name,
24
+ description,
25
+ parameters: {
26
+ type: "object",
27
+ properties: {
28
+ reason: {
29
+ type: "string",
30
+ description: "explain how this action will help to complete the task. the reason should align with the task provided",
31
+ },
32
+ action: {
33
+ type: "string",
34
+ description: `explain the next action in natural language.
35
+ The next action should be as atomic as possible, precise and should contain enough details about the action to be performed.
36
+ E.g. each click, key press, input, assert, observation should be a separate action.
37
+ Each action should take the task to completion, if not the action is invalid.
38
+ If the element is not visible then action should be scroll.`,
39
+ },
40
+ element_description: {
41
+ type: "string",
42
+ description: "The description of the element on which action needs to be taken, including its position, appearance, etc.",
43
+ },
44
+ is_element_visible: {
45
+ type: "boolean",
46
+ description: "A boolean to indicate whether the concerned element is visible in the screenshot.",
47
+ },
48
+ ...additionalProperties,
49
+ },
50
+ required: [
51
+ "reason",
52
+ "action",
53
+ "element_description",
54
+ "is_element_visible",
55
+ ...Object.keys(additionalProperties),
56
+ ],
57
+ },
58
+ },
59
+ });
60
+ function getActionToolCalls() {
61
+ return [
62
+ createActionCall(ActionType.ASSERT_TEXT, "assert whether the given element on the page is visible", {
63
+ assertion_text: {
64
+ type: "string",
65
+ description: "The text for which the visibility needs to be asserted.",
66
+ },
67
+ }),
68
+ createActionCall(ActionType.FILL, "fill the input element with a particular text"),
69
+ createActionCall(ActionType.CLICK, "click an element on the page"),
70
+ createActionCall(ActionType.PAGE_GOTO, "navigate the page to a new URL"),
71
+ createActionCall(ActionType.PRESS_ACTION, "Focuses the matching element and presses a combination of the keys"),
72
+ createActionCall(ActionType.HOVER, "hover over an element on the page"),
73
+ createActionCall(ActionType.SCROLL, "Scroll the page since element is not visible in the screenshot", {
74
+ element: {
75
+ type: "string",
76
+ description: "Element to look for after scrolling to complete the task.",
77
+ },
78
+ }),
79
+ createActionCall(ActionType.OBSERVATION, "Observation based on the task provided. If the task doesn't explicitly mention any browser interaction, and instead, asks questions to be answered — use this tool call", {
80
+ observation: {
81
+ type: "string",
82
+ description: "Observation based on the task provided.",
83
+ },
84
+ }),
85
+ ];
86
+ }
87
+ exports.getActionToolCalls = getActionToolCalls;
@@ -0,0 +1,9 @@
1
+ export type ServerFixture = {
2
+ port: number;
3
+ baseURL: string;
4
+ };
5
+ export declare const expect: import("@playwright/test").Expect<{}>;
6
+ export declare const test: import("@playwright/test").TestType<import("@playwright/test").PlaywrightTestArgs & import("@playwright/test").PlaywrightTestOptions, import("@playwright/test").PlaywrightWorkerArgs & import("@playwright/test").PlaywrightWorkerOptions & {
7
+ server: ServerFixture;
8
+ }>;
9
+ //# sourceMappingURL=fixtures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../../../src/agent/master/browser-tests/fixtures.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,MAAM,uCAAc,CAAC;AAClC,eAAO,MAAM,IAAI;YAA6B,aAAa;EAsBzD,CAAC"}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.test = exports.expect = void 0;
7
+ const test_1 = require("@playwright/test");
8
+ const http_server_1 = __importDefault(require("http-server"));
9
+ const path_1 = __importDefault(require("path"));
10
+ exports.expect = test_1.test.expect;
11
+ exports.test = test_1.test.extend({
12
+ server: [
13
+ // eslint-disable-next-line no-empty-pattern
14
+ async ({}, use, workerInfo) => {
15
+ const port = 2345 + workerInfo.workerIndex;
16
+ const server = http_server_1.default.createServer({
17
+ root: path_1.default.join(process.cwd(), "test-data"),
18
+ });
19
+ await new Promise((resolve) => {
20
+ server.listen(port, () => {
21
+ console.log(`Server running at http://localhost:${port}`);
22
+ resolve();
23
+ });
24
+ });
25
+ await use({
26
+ port,
27
+ baseURL: `http://localhost:${port}`,
28
+ });
29
+ server.close();
30
+ },
31
+ { scope: "worker" },
32
+ ],
33
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.spec.d.ts","sourceRoot":"","sources":["../../../../src/agent/master/browser-tests/index.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const fs_1 = __importDefault(require("fs"));
7
+ const path_1 = __importDefault(require("path"));
8
+ const utils_1 = require("../../browsing/utils");
9
+ const element_annotation_1 = require("../element-annotation");
10
+ const run_1 = require("../run");
11
+ const fixtures_1 = require("./fixtures");
12
+ (0, fixtures_1.test)("able to scroll and interact with elements", async ({ page, server }) => {
13
+ await page.goto(`${server.baseURL}/blog-page.html`);
14
+ const response = await (0, run_1.createTestUsingMasterAgent)({
15
+ task: `fill test@test.com into the email field and click the submit`,
16
+ page,
17
+ options: {},
18
+ });
19
+ console.log(response);
20
+ (0, fixtures_1.expect)(response.importPaths.length).toBe(0);
21
+ (0, fixtures_1.expect)(response.code).toContain("await page.getByPlaceholder('Enter your email').fill(\"test@test.com\")");
22
+ (0, fixtures_1.expect)(response.code).toContain("await page.getByRole('button', { name: 'Subscribe' }).click()");
23
+ });
24
+ (0, fixtures_1.test)("scroll when element does not exist", async ({ page, server }) => {
25
+ await page.goto(`${server.baseURL}/blog-page.html`);
26
+ const response = await (0, run_1.createTestUsingMasterAgent)({
27
+ task: `click search button`,
28
+ page,
29
+ options: {},
30
+ });
31
+ console.log(response);
32
+ (0, fixtures_1.expect)(response.importPaths.length).toBe(0);
33
+ (0, fixtures_1.expect)(response.code.length).toBe(0);
34
+ });
35
+ (0, fixtures_1.test)("scroll and click inside div elements", async ({ page, server }) => {
36
+ await page.goto(`${server.baseURL}/dropdown-scrolls.html`);
37
+ const response = await (0, run_1.createTestUsingMasterAgent)({
38
+ task: `click on x-3 inside bmw dropdown, and then,
39
+ click on maverick inside ford dropdown`,
40
+ page,
41
+ options: {},
42
+ });
43
+ console.log(response);
44
+ (0, fixtures_1.expect)(response.importPaths.length).toBe(0);
45
+ (0, fixtures_1.expect)(response.code.length).toBeGreaterThan(0);
46
+ const lines = response.code.split("\n");
47
+ (0, fixtures_1.expect)(lines.find((l) => l.match(/^await page.+BMW.+.click/))).toBeTruthy();
48
+ (0, fixtures_1.expect)(lines.find((l) => l.match(/^await page.+X3.+.click/))).toBeTruthy();
49
+ (0, fixtures_1.expect)(lines.find((l) => l.match(/^await page.+Ford.+.click/))).toBeTruthy();
50
+ (0, fixtures_1.expect)(lines.find((l) => l.match(/^await page.+Maverick.+.click/))).toBeTruthy();
51
+ });
52
+ (0, fixtures_1.test)("agent can click icons accurately", async ({ page, server }) => {
53
+ await page.goto(`${server.baseURL}/icons-navbar.html`);
54
+ await (0, fixtures_1.expect)(page.getByText("select an icon")).toBeVisible();
55
+ const response = await (0, run_1.createTestUsingMasterAgent)({
56
+ task: `click on the gear icon`,
57
+ page,
58
+ options: {},
59
+ });
60
+ // Validate code generated and action performed
61
+ await (0, fixtures_1.expect)(page.getByText("you clicked Gear")).toBeVisible();
62
+ console.log(response);
63
+ (0, fixtures_1.expect)(response.importPaths.length).toBe(0);
64
+ (0, fixtures_1.expect)(response.code).toContain("page.locator");
65
+ (0, fixtures_1.expect)(response.code).toContain("click()");
66
+ // Validate icons registry
67
+ const iconsRegistryFile = path_1.default.join(process.cwd(), ".empiricalrun", "icons.json");
68
+ const icons = JSON.parse(fs_1.default.readFileSync(iconsRegistryFile, "utf-8"));
69
+ (0, fixtures_1.expect)(icons.length).toBeGreaterThan(0);
70
+ // Commenting out this check since with parallel test executions,
71
+ // we can have icons from other tests in the same file
72
+ // expect(icons.length).toBe(4); // 1 for each unique icon
73
+ fs_1.default.unlinkSync(iconsRegistryFile);
74
+ });
75
+ (0, fixtures_1.test)("annotate and enrich annotations correctly", async ({ page, server }) => {
76
+ await (0, utils_1.injectPwLocatorGenerator)(page);
77
+ await page.goto(`${server.baseURL}/iframe-elements.html`);
78
+ const { annotationKeys: keys } = await (0, element_annotation_1.getAnnotationKeys)({
79
+ page,
80
+ preference: {
81
+ actionType: "all",
82
+ },
83
+ });
84
+ console.log(keys);
85
+ (0, fixtures_1.expect)(keys.length).toBe(6);
86
+ // 2 icons: 1 in main frame, 1 in iframe
87
+ (0, fixtures_1.expect)(keys.filter((k) => k.text.includes("icon") && k.text.includes("close"))
88
+ .length).toBe(2);
89
+ // 2 text inputs: 1 in main frame, 1 in iframe
90
+ (0, fixtures_1.expect)(keys.filter((k) => k.text.includes("Enter your name")).length).toBe(2);
91
+ // 2 clickable divs: 1 in main frame, 1 in iframe
92
+ (0, fixtures_1.expect)(keys.filter((k) => k.text.includes("Lorem Ipsum")).length).toBe(2);
93
+ });
94
+ (0, fixtures_1.test)("fill action with multiple pages", async ({ context }) => {
95
+ const page1 = await context.newPage();
96
+ const page2 = await context.newPage();
97
+ const response = await (0, run_1.createTestUsingMasterAgent)({
98
+ task: `goto empirical.run on page1 and goto github.com/search in page2. Enter text empirical on page2 and click on search.`,
99
+ page: page2,
100
+ options: {},
101
+ scopeVars: {
102
+ context,
103
+ page1,
104
+ page2,
105
+ },
106
+ });
107
+ (0, fixtures_1.expect)(response.code).toBeTruthy();
108
+ console.log(response.code);
109
+ const lines = response.code.split("\n");
110
+ (0, fixtures_1.expect)(lines.find((l) => l.match(/^await page1\.goto(.+)empirical\.run/))).toBeTruthy();
111
+ (0, fixtures_1.expect)(lines.find((l) => l.match(/^await page2\.goto(.+)github\.com\/search/))).toBeTruthy();
112
+ (0, fixtures_1.expect)(lines.find((l) => l.match(/^await page2(.+)fill(.+)empirical/))).toBeTruthy();
113
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=skills.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.spec.d.ts","sourceRoot":"","sources":["../../../../src/agent/master/browser-tests/skills.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const fs_1 = __importDefault(require("fs"));
7
+ const run_1 = require("../run");
8
+ const fixtures_1 = require("./fixtures");
9
+ fixtures_1.test.describe.configure({ mode: "default" });
10
+ fixtures_1.test.beforeEach(async () => {
11
+ // Setup repo with POM file
12
+ fs_1.default.mkdirSync("pages");
13
+ const pomContent = `
14
+ import type { Page } from "@playwright/test";
15
+
16
+ export async function subscribeToBlog({ page, email }: { page: Page; email: string }) {
17
+ await page.getByPlaceholder("Enter your email").fill(email);
18
+ await page.getByRole("button", { name: "Subscribe" }).click();
19
+ }
20
+
21
+ export async function extractTitleForPost({ page, nth }: { page: Page; nth: number }) {
22
+ // nth is zero-indexed
23
+ const title = await page.locator("h2").nth(nth).textContent();
24
+ return title;
25
+ }
26
+ `;
27
+ fs_1.default.writeFileSync("pages/blog.ts", pomContent);
28
+ });
29
+ fixtures_1.test.afterEach(async () => {
30
+ // Clean up the repo in cwd
31
+ fs_1.default.rmSync("pages", { recursive: true });
32
+ });
33
+ (0, fixtures_1.test)("use skills to subscribe to blog", async ({ page, server }) => {
34
+ await page.goto(`${server.baseURL}/blog-page.html`);
35
+ const response = await (0, run_1.createTestUsingMasterAgent)({
36
+ task: `subscribe as user@example.com`,
37
+ page,
38
+ testCase: {
39
+ id: 1,
40
+ name: "subscribe to blog",
41
+ steps: ["subscribe as user@example.com"],
42
+ filePath: "blog.spec.ts",
43
+ suites: [],
44
+ },
45
+ options: {},
46
+ });
47
+ // Assert execution was successful
48
+ await (0, fixtures_1.expect)(page.getByText("Thanks for subscribing")).toBeVisible();
49
+ // Assert code generated is correct
50
+ console.log(response);
51
+ (0, fixtures_1.expect)(response.importPaths.length).toBeGreaterThan(0);
52
+ (0, fixtures_1.expect)(response.importPaths[0]).toBe("pages/blog.ts");
53
+ (0, fixtures_1.expect)(response.code.length).toBeGreaterThan(0);
54
+ (0, fixtures_1.expect)(response.code).toMatch(/await.*subscribeToBlog.*page.*email.*user@example\.com/);
55
+ });
56
+ (0, fixtures_1.test)("use skills to extract blog post title", async ({ page, server }) => {
57
+ await page.goto(`${server.baseURL}/blog-page.html`);
58
+ const response = await (0, run_1.createTestUsingMasterAgent)({
59
+ // TODO: Extend this to click on "read more" and verify generated code
60
+ // uses the state variable created by the skill
61
+ task: `extract title of 2nd blog post`,
62
+ page,
63
+ testCase: {
64
+ id: 1,
65
+ name: "extract blog post title",
66
+ steps: ["extract title of 2nd blog post"],
67
+ filePath: "blog.spec.ts",
68
+ suites: [],
69
+ },
70
+ options: {},
71
+ });
72
+ // Assert code generated is correct
73
+ console.log(response);
74
+ (0, fixtures_1.expect)(response.importPaths.length).toBeGreaterThan(0);
75
+ (0, fixtures_1.expect)(response.importPaths[0]).toBe("pages/blog.ts");
76
+ (0, fixtures_1.expect)(response.code.length).toBeGreaterThan(0);
77
+ (0, fixtures_1.expect)(response.code).toMatch(/^const.*=.*await extractTitleForPost.*page.*nth:.*1/);
78
+ });
79
+ (0, fixtures_1.test)("use skills to subscribe with multiple pages", async ({ page, server, }) => {
80
+ await page.goto(`${server.baseURL}/icons-navbar.html`);
81
+ const blogPage = await page.context().newPage();
82
+ await blogPage.goto(`${server.baseURL}/blog-page.html`);
83
+ const response = await (0, run_1.createTestUsingMasterAgent)({
84
+ task: `we have 2 pages open inside a web browser, and your task is to subscribe as user@example.com on the blogPage`,
85
+ page,
86
+ testCase: {
87
+ id: 1,
88
+ name: "subscribe to blog",
89
+ steps: [
90
+ "we have 2 pages open inside a web browser, and your task is to subscribe as user@example.com on the blogPage",
91
+ ],
92
+ filePath: "blog.spec.ts",
93
+ suites: [],
94
+ },
95
+ scopeVars: {
96
+ page,
97
+ blogPage,
98
+ },
99
+ options: {},
100
+ });
101
+ // Assert execution was successful
102
+ await (0, fixtures_1.expect)(blogPage.getByText("Thanks for subscribing")).toBeVisible();
103
+ // Assert code generated is correct
104
+ console.log(response);
105
+ (0, fixtures_1.expect)(response.importPaths.length).toBeGreaterThan(0);
106
+ (0, fixtures_1.expect)(response.importPaths[0]).toBe("pages/blog.ts");
107
+ (0, fixtures_1.expect)(response.code.length).toBeGreaterThan(0);
108
+ (0, fixtures_1.expect)(response.code).toMatch(/await.*subscribeToBlog.*blogPage.*email.*user@example\.com/);
109
+ });
@@ -0,0 +1,30 @@
1
+ import { LLM, TraceClient } from "@empiricalrun/llm";
2
+ import { TestGenConfigOptions } from "@empiricalrun/shared-types";
3
+ import { Page } from "playwright";
4
+ import { ActionType } from "./action-tool-calls";
5
+ export declare function getElementAnnotation({ elementDescription, annotations, annotatedScreenshot, trace, llm, options, preference, }: {
6
+ elementDescription: string;
7
+ annotations: string;
8
+ annotatedScreenshot: string;
9
+ trace?: TraceClient;
10
+ llm?: LLM;
11
+ options?: TestGenConfigOptions;
12
+ preference: AnnotationPreference;
13
+ }): Promise<string | undefined>;
14
+ export type AnnotationPreference = {
15
+ actionType: "all" | ActionType.FILL | ActionType.ASSERT_TEXT | ActionType.SCROLL;
16
+ assertionText?: string | undefined;
17
+ };
18
+ export declare function getAnnotationKeys({ page, preference, trace, }: {
19
+ page: Page;
20
+ preference: AnnotationPreference;
21
+ trace?: TraceClient;
22
+ }): Promise<{
23
+ annotationKeys: {
24
+ elementID: string;
25
+ text: string;
26
+ }[];
27
+ annotationBuffer: Buffer;
28
+ annotatedPageScreenshot: string;
29
+ }>;
30
+ //# sourceMappingURL=element-annotation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"element-annotation.d.ts","sourceRoot":"","sources":["../../../src/agent/master/element-annotation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,GAAG,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AASlC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AA2DjD,wBAAsB,oBAAoB,CAAC,EACzC,kBAAkB,EAClB,WAAW,EACX,mBAAmB,EACnB,KAAK,EACL,GAAG,EACH,OAAO,EACP,UAAU,GACX,EAAE;IACD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,UAAU,EAAE,oBAAoB,CAAC;CAClC,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA8C9B;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,UAAU,EACN,KAAK,GACL,UAAU,CAAC,IAAI,GACf,UAAU,CAAC,WAAW,GACtB,UAAU,CAAC,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC,CAAC;AAgBF,wBAAsB,iBAAiB,CAAC,EACtC,IAAI,EACJ,UAAU,EACV,KAAK,GACN,EAAE;IACD,IAAI,EAAE,IAAI,CAAC;IACX,UAAU,EAAE,oBAAoB,CAAC;IACjC,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,GAAG,OAAO,CAAC;IACV,cAAc,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACtD,gBAAgB,EAAE,MAAM,CAAC;IACzB,uBAAuB,EAAE,MAAM,CAAC;CACjC,CAAC,CAoFD"}