@copado/agentia-cli 1.2.0 → 1.4.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 (302) hide show
  1. package/CHANGELOG.md +58 -1
  2. package/README.md +2299 -1615
  3. package/dist/commands/auth/get.js +21 -1
  4. package/dist/commands/auth/set.js +13 -0
  5. package/dist/commands/auth/unset.js +37 -0
  6. package/dist/commands/cicd/cloud/commit.js +6 -5
  7. package/dist/commands/cicd/cloud/promote.js +44 -8
  8. package/dist/commands/cicd/credential/auth/status.js +2 -2
  9. package/dist/commands/cicd/credential/auth/web/login.js +2 -2
  10. package/dist/commands/cicd/credential/create.js +2 -2
  11. package/dist/commands/cicd/credential/list.js +4 -3
  12. package/dist/commands/cicd/credential/open.js +2 -2
  13. package/dist/commands/cicd/credential/update.js +2 -2
  14. package/dist/commands/cicd/data/commit/create.js +2 -2
  15. package/dist/commands/cicd/data/commit/list.js +2 -2
  16. package/dist/commands/cicd/data/dataset-file/content.js +2 -2
  17. package/dist/commands/cicd/data/dataset-file/list.js +2 -2
  18. package/dist/commands/cicd/data/filter/add.js +2 -2
  19. package/dist/commands/cicd/data/filter/delete.js +2 -2
  20. package/dist/commands/cicd/data/filter/list.js +2 -2
  21. package/dist/commands/cicd/data/filter/update.js +2 -2
  22. package/dist/commands/cicd/data/formula/create.js +2 -2
  23. package/dist/commands/cicd/data/formula/list.js +2 -2
  24. package/dist/commands/cicd/data/formula/update.js +2 -2
  25. package/dist/commands/cicd/data/records/match.js +2 -2
  26. package/dist/commands/cicd/data/records/search.js +2 -2
  27. package/dist/commands/cicd/data/sobject/fields.js +2 -2
  28. package/dist/commands/cicd/data/sobject/relationships.js +2 -2
  29. package/dist/commands/cicd/data/sync/apply.js +2 -2
  30. package/dist/commands/cicd/data/sync/preview-updates.js +2 -2
  31. package/dist/commands/cicd/data/template/convert-old.js +2 -2
  32. package/dist/commands/cicd/data/template/create.js +2 -2
  33. package/dist/commands/cicd/data/template/delete.js +2 -2
  34. package/dist/commands/cicd/data/template/get-detail.js +2 -2
  35. package/dist/commands/cicd/data/template/get.js +2 -2
  36. package/dist/commands/cicd/data/template/list.js +2 -2
  37. package/dist/commands/cicd/data/template/open.js +2 -2
  38. package/dist/commands/cicd/data/template/save-detail.js +2 -2
  39. package/dist/commands/cicd/environment/auth/status.js +2 -2
  40. package/dist/commands/cicd/environment/auth/web/login.js +2 -2
  41. package/dist/commands/cicd/environment/create.js +2 -2
  42. package/dist/commands/cicd/environment/get.js +2 -2
  43. package/dist/commands/cicd/environment/list.js +4 -3
  44. package/dist/commands/cicd/environment/open.js +2 -2
  45. package/dist/commands/cicd/environment/update.js +2 -2
  46. package/dist/commands/cicd/extension/create.js +2 -2
  47. package/dist/commands/cicd/extension/install.js +2 -2
  48. package/dist/commands/cicd/extension/package.js +2 -2
  49. package/dist/commands/cicd/extension/publish.js +2 -2
  50. package/dist/commands/cicd/extension/uninstall.js +2 -2
  51. package/dist/commands/cicd/extension/validate.js +2 -2
  52. package/dist/commands/cicd/extension-configuration/get.js +2 -2
  53. package/dist/commands/cicd/extension-configuration/list.js +4 -3
  54. package/dist/commands/cicd/extension-configuration/open.js +2 -2
  55. package/dist/commands/cicd/function/defaults.js +2 -2
  56. package/dist/commands/cicd/function/delete.js +2 -2
  57. package/dist/commands/cicd/function/get.js +2 -2
  58. package/dist/commands/cicd/function/list.js +12 -15
  59. package/dist/commands/cicd/function/open.js +2 -2
  60. package/dist/commands/cicd/function/result/get.js +2 -2
  61. package/dist/commands/cicd/function/result/log/get.js +2 -2
  62. package/dist/commands/cicd/function/run-local.js +2 -2
  63. package/dist/commands/cicd/function/run.js +2 -2
  64. package/dist/commands/cicd/function/upsert.js +2 -2
  65. package/dist/commands/cicd/health-check.js +2 -2
  66. package/dist/commands/cicd/job/get.js +2 -2
  67. package/dist/commands/cicd/job/kill.js +2 -2
  68. package/dist/commands/cicd/job/list.js +4 -3
  69. package/dist/commands/cicd/job/log/get.js +2 -2
  70. package/dist/commands/cicd/job/open.js +2 -2
  71. package/dist/commands/cicd/job/pause.js +2 -2
  72. package/dist/commands/cicd/job/result-file/get.js +13 -8
  73. package/dist/commands/cicd/job/result-file/list.js +2 -2
  74. package/dist/commands/cicd/job/resume.js +2 -2
  75. package/dist/commands/cicd/job/run.js +2 -2
  76. package/dist/commands/cicd/metadata/content/compare.js +2 -2
  77. package/dist/commands/cicd/metadata/content/get.js +2 -2
  78. package/dist/commands/cicd/metadata/dependency/list.js +44 -21
  79. package/dist/commands/cicd/metadata/explore.js +2 -2
  80. package/dist/commands/cicd/metadata/index/compare.js +2 -2
  81. package/dist/commands/cicd/metadata/list.js +2 -2
  82. package/dist/commands/cicd/metadata/refresh/deleted.js +2 -2
  83. package/dist/commands/cicd/metadata/refresh/run.js +2 -2
  84. package/dist/commands/cicd/metadata/refresh/status.js +2 -2
  85. package/dist/commands/cicd/notification/configure.js +2 -2
  86. package/dist/commands/cicd/notification/get.js +2 -2
  87. package/dist/commands/cicd/pipeline/automation/activate.js +2 -2
  88. package/dist/commands/cicd/pipeline/automation/create.js +2 -2
  89. package/dist/commands/cicd/pipeline/automation/deactivate.js +2 -2
  90. package/dist/commands/cicd/pipeline/automation/delete.js +2 -2
  91. package/dist/commands/cicd/pipeline/automation/get.js +2 -2
  92. package/dist/commands/cicd/pipeline/automation/list.js +4 -3
  93. package/dist/commands/cicd/pipeline/automation/open.js +2 -2
  94. package/dist/commands/cicd/pipeline/automation/update.js +2 -2
  95. package/dist/commands/cicd/pipeline/connection/create.js +2 -2
  96. package/dist/commands/cicd/pipeline/connection/delete.js +2 -2
  97. package/dist/commands/cicd/pipeline/connection/list.js +2 -2
  98. package/dist/commands/cicd/pipeline/connection/open.js +2 -2
  99. package/dist/commands/cicd/pipeline/connection/update.js +2 -2
  100. package/dist/commands/cicd/pipeline/create.js +2 -2
  101. package/dist/commands/cicd/pipeline/get.js +2 -2
  102. package/dist/commands/cicd/pipeline/list.js +4 -3
  103. package/dist/commands/cicd/pipeline/open.js +2 -2
  104. package/dist/commands/cicd/pipeline/quality-gate/activate.js +2 -2
  105. package/dist/commands/cicd/pipeline/quality-gate/create.js +2 -2
  106. package/dist/commands/cicd/pipeline/quality-gate/deactivate.js +2 -2
  107. package/dist/commands/cicd/pipeline/quality-gate/delete.js +2 -2
  108. package/dist/commands/cicd/pipeline/quality-gate/get.js +2 -2
  109. package/dist/commands/cicd/pipeline/quality-gate/list.js +4 -3
  110. package/dist/commands/cicd/pipeline/quality-gate/open.js +2 -2
  111. package/dist/commands/cicd/pipeline/quality-gate/update.js +2 -2
  112. package/dist/commands/cicd/pipeline/stage-connection/create.js +2 -2
  113. package/dist/commands/cicd/pipeline/stage-connection/delete.js +2 -2
  114. package/dist/commands/cicd/pipeline/stage-connection/list.js +2 -2
  115. package/dist/commands/cicd/pipeline/stage-connection/open.js +2 -2
  116. package/dist/commands/cicd/pipeline/stage-connection/update.js +2 -2
  117. package/dist/commands/cicd/pipeline/update.js +2 -2
  118. package/dist/commands/cicd/project/create.js +2 -2
  119. package/dist/commands/cicd/project/default/get.js +2 -2
  120. package/dist/commands/cicd/project/default/set.js +2 -2
  121. package/dist/commands/cicd/project/default/unset.js +2 -2
  122. package/dist/commands/cicd/project/delete.js +2 -2
  123. package/dist/commands/cicd/project/get.js +2 -2
  124. package/dist/commands/cicd/project/list.js +4 -3
  125. package/dist/commands/cicd/project/open.js +2 -2
  126. package/dist/commands/cicd/project/update.js +2 -2
  127. package/dist/commands/cicd/promotion/conflict/get.js +2 -2
  128. package/dist/commands/cicd/promotion/conflict/list.js +2 -2
  129. package/dist/commands/cicd/promotion/conflict/resolve.js +2 -2
  130. package/dist/commands/cicd/promotion/conflict/unresolve.js +2 -2
  131. package/dist/commands/cicd/promotion/get.js +2 -2
  132. package/dist/commands/cicd/promotion/job-step/update.js +2 -2
  133. package/dist/commands/cicd/promotion/list.js +4 -3
  134. package/dist/commands/cicd/promotion/open.js +2 -2
  135. package/dist/commands/cicd/promotion/queue/list.js +28 -0
  136. package/dist/commands/cicd/promotion/queue/remove.js +37 -0
  137. package/dist/commands/cicd/promotion/run.js +2 -2
  138. package/dist/commands/cicd/promotion/status.js +29 -0
  139. package/dist/commands/cicd/repository/auth/https/configure.js +2 -2
  140. package/dist/commands/cicd/repository/auth/oauth/login.js +2 -2
  141. package/dist/commands/cicd/repository/auth/setup.js +2 -2
  142. package/dist/commands/cicd/repository/auth/ssh/configure.js +2 -2
  143. package/dist/commands/cicd/repository/create.js +2 -2
  144. package/dist/commands/cicd/repository/delete.js +2 -2
  145. package/dist/commands/cicd/repository/get.js +2 -2
  146. package/dist/commands/cicd/repository/list.js +7 -10
  147. package/dist/commands/cicd/repository/open.js +2 -2
  148. package/dist/commands/cicd/repository/reset.js +2 -2
  149. package/dist/commands/cicd/repository/update.js +2 -2
  150. package/dist/commands/cicd/repository/validate.js +2 -2
  151. package/dist/commands/cicd/stage/create.js +2 -2
  152. package/dist/commands/cicd/stage/delete.js +2 -2
  153. package/dist/commands/cicd/stage/get.js +2 -2
  154. package/dist/commands/cicd/stage/list.js +4 -3
  155. package/dist/commands/cicd/stage/open.js +2 -2
  156. package/dist/commands/cicd/stage/update.js +2 -2
  157. package/dist/commands/cicd/template/defaults.js +2 -2
  158. package/dist/commands/cicd/template/delete.js +2 -2
  159. package/dist/commands/cicd/template/get.js +2 -2
  160. package/dist/commands/cicd/template/list.js +11 -14
  161. package/dist/commands/cicd/template/upsert.js +2 -2
  162. package/dist/commands/cicd/user/get.js +2 -2
  163. package/dist/commands/cicd/work/ahead-behind.js +2 -2
  164. package/dist/commands/cicd/work/create.js +2 -2
  165. package/dist/commands/cicd/work/delete.js +4 -4
  166. package/dist/commands/cicd/work/deployment-step/create.js +2 -2
  167. package/dist/commands/cicd/work/deployment-step/delete.js +2 -2
  168. package/dist/commands/cicd/work/deployment-step/list.js +2 -2
  169. package/dist/commands/cicd/work/deployment-step/reorder.js +2 -2
  170. package/dist/commands/cicd/work/deployment-step/salesforce-flows.js +2 -2
  171. package/dist/commands/cicd/work/deployment-step/types.js +2 -2
  172. package/dist/commands/cicd/work/deployment-step/update.js +2 -2
  173. package/dist/commands/cicd/work/done.js +2 -2
  174. package/dist/commands/cicd/work/environment-sync.js +140 -64
  175. package/dist/commands/cicd/work/get.js +4 -4
  176. package/dist/commands/cicd/work/list.js +4 -3
  177. package/dist/commands/cicd/work/open.js +2 -2
  178. package/dist/commands/cicd/work/promote.js +2 -2
  179. package/dist/commands/cicd/work/publish.js +2 -2
  180. package/dist/commands/cicd/work/push.js +2 -2
  181. package/dist/commands/cicd/work/set.js +2 -2
  182. package/dist/commands/cicd/work/status.js +2 -2
  183. package/dist/commands/cicd/work/submit.js +2 -2
  184. package/dist/commands/cicd/work/test/apex.js +20 -35
  185. package/dist/commands/cicd/work/test.js +116 -11
  186. package/dist/commands/cicd/work/update.js +4 -4
  187. package/dist/commands/help-agent.js +15 -0
  188. package/dist/commands/help.js +38 -0
  189. package/dist/commands/history/clear.js +42 -0
  190. package/dist/commands/history/list.js +50 -0
  191. package/dist/commands/support.js +15 -0
  192. package/dist/commands/testing/browser/execute.js +49 -0
  193. package/dist/commands/testing/browser/history.js +49 -0
  194. package/dist/commands/testing/browser/inspect.js +35 -0
  195. package/dist/commands/testing/browser/recorder.js +52 -0
  196. package/dist/commands/testing/browser/screenshot.js +27 -0
  197. package/dist/commands/testing/browser/set-options.js +35 -0
  198. package/dist/commands/testing/browser/start.js +51 -0
  199. package/dist/commands/testing/browser/status.js +26 -0
  200. package/dist/commands/testing/browser/stop.js +34 -0
  201. package/dist/commands/testing/browser/view.js +35 -0
  202. package/dist/commands/testing/job/runs/abort.js +1 -1
  203. package/dist/commands/testing/job/runs/get.js +1 -1
  204. package/dist/commands/testing/job/runs/list.js +1 -1
  205. package/dist/commands/testing/job/runs/logs.js +1 -1
  206. package/dist/commands/testing/job/runs/search.js +1 -1
  207. package/dist/hooks/init/cicd-connection.js +59 -0
  208. package/dist/lib/agentia-command.js +69 -6
  209. package/dist/lib/cicd-command.js +3 -0
  210. package/dist/lib/cicd-connection.js +22 -0
  211. package/dist/lib/cicd-gateway.js +2 -1
  212. package/dist/lib/command-history-sanitization.js +9 -0
  213. package/dist/lib/command-history.js +11 -0
  214. package/dist/lib/command-output-buffer.js +6 -1
  215. package/dist/lib/defaults-store.js +5 -1
  216. package/dist/lib/dependency-from-changes.js +3 -1
  217. package/dist/lib/dependency-source-context.js +3 -0
  218. package/dist/lib/function-list.js +3 -0
  219. package/dist/lib/git-worktree.js +4 -1
  220. package/dist/lib/help-agent-command.js +3 -0
  221. package/dist/lib/help-agent-interaction-history.js +10 -0
  222. package/dist/lib/help-agent-session.js +3 -0
  223. package/dist/lib/job-get.js +2 -1
  224. package/dist/lib/job-types.js +2 -1
  225. package/dist/lib/list-pagination.js +6 -1
  226. package/dist/lib/local-quality-gates.js +4 -1
  227. package/dist/lib/mcp/result.js +41 -3
  228. package/dist/lib/mcp/server.js +3 -2
  229. package/dist/lib/mcp/testing-browser-tools.js +179 -0
  230. package/dist/lib/mcp/testing-tools.js +4 -3
  231. package/dist/lib/mcp/tool-annotations.js +31 -12
  232. package/dist/lib/mcp/tools.js +115 -59
  233. package/dist/lib/mcp/work-tools.js +100 -47
  234. package/dist/lib/promotion-queue.js +5 -0
  235. package/dist/lib/promotion-run.js +4 -1
  236. package/dist/lib/promotion-status.js +12 -0
  237. package/dist/lib/quality-gates.js +13 -0
  238. package/dist/lib/repository-list.js +3 -0
  239. package/dist/lib/runtime.js +1 -1
  240. package/dist/lib/stock-quality-gates.js +2 -1
  241. package/dist/lib/support-ai-context.js +11 -0
  242. package/dist/lib/support-ai-stream-parser.js +4 -0
  243. package/dist/lib/support-ai.js +9 -0
  244. package/dist/lib/template-list.js +3 -0
  245. package/dist/lib/testing-browser-command.js +6 -0
  246. package/dist/lib/testing-browser-operations.js +16 -0
  247. package/dist/lib/testing-browser-requests.js +11 -0
  248. package/dist/lib/testing-browser-robot.js +9 -0
  249. package/dist/lib/testing-browser-session.js +13 -0
  250. package/dist/lib/testing-browser-state.js +17 -0
  251. package/dist/lib/testing-browser-stream.js +7 -0
  252. package/dist/lib/testing-browser-types.js +3 -0
  253. package/dist/lib/testing-browser-viewer-key.js +7 -0
  254. package/dist/lib/testing-gateway.js +2 -1
  255. package/dist/lib/testing-operations.js +21 -1
  256. package/dist/lib/testing-sanitization.js +2 -1
  257. package/dist/lib/work-apex-test-failures.js +2 -1
  258. package/dist/lib/work-environment-sync-ready.js +7 -1
  259. package/dist/lib/work-environment-sync.js +8 -1
  260. package/dist/lib/work-local-run-tests.js +2 -1
  261. package/dist/lib/work-promote-deploy.js +3 -1
  262. package/dist/lib/work-promote.js +2 -1
  263. package/dist/lib/work-types.js +3 -1
  264. package/oclif.manifest.json +3544 -1828
  265. package/package.json +11 -4
  266. package/templates/skills/agentia-ai/SKILL.md +6 -2
  267. package/templates/skills/agentia-ai/references/ai-agents.md +19 -1
  268. package/templates/skills/agentia-cicd/SKILL.md +6 -5
  269. package/templates/skills/agentia-cicd/references/environments-and-credentials.md +16 -0
  270. package/templates/skills/agentia-cicd/references/jobs.md +3 -2
  271. package/templates/skills/agentia-cicd/references/promotions.md +26 -5
  272. package/templates/skills/agentia-cicd/references/work.md +25 -11
  273. package/templates/skills/agentia-metadata/SKILL.md +9 -3
  274. package/templates/skills/agentia-metadata/references/metadata-dependency.md +70 -0
  275. package/templates/skills/agentia-metadata/references/metadata-explore.md +8 -4
  276. package/templates/skills/agentia-testing/SKILL.md +9 -4
  277. package/templates/skills/agentia-testing/references/browser-testing.md +92 -0
  278. package/templates/skills/agentia-testing/references/flow-automation.md +112 -0
  279. package/templates/skills/agentia-testing/references/qforce.md +88 -0
  280. package/templates/skills/agentia-testing/references/qweb.md +103 -0
  281. package/templates/skills/agentia-testing/references/tests.md +17 -9
  282. package/vendor/java/var-replace-command.jar +0 -0
  283. package/dist/commands/testing/live/continue.js +0 -16
  284. package/dist/commands/testing/live/execute.js +0 -43
  285. package/dist/commands/testing/live/history.js +0 -40
  286. package/dist/commands/testing/live/inspect.js +0 -31
  287. package/dist/commands/testing/live/interrupt.js +0 -16
  288. package/dist/commands/testing/live/recorder.js +0 -42
  289. package/dist/commands/testing/live/reports.js +0 -31
  290. package/dist/commands/testing/live/screenshot.js +0 -25
  291. package/dist/commands/testing/live/set-options.js +0 -35
  292. package/dist/commands/testing/live/start.js +0 -58
  293. package/dist/commands/testing/live/status.js +0 -24
  294. package/dist/commands/testing/live/stop.js +0 -36
  295. package/dist/commands/testing/live/view.js +0 -36
  296. package/dist/lib/mcp/testing-live-tools.js +0 -226
  297. package/dist/lib/testing-live-command.js +0 -8
  298. package/dist/lib/testing-live-operations.js +0 -25
  299. package/dist/lib/testing-live-recorder.js +0 -11
  300. package/dist/lib/testing-live-robot.js +0 -9
  301. package/dist/lib/testing-live-state.js +0 -12
  302. package/dist/lib/testing-live-types.js +0 -3
@@ -0,0 +1,92 @@
1
+ <!-- Agentia managed skill file: agentia setup skills -->
2
+
3
+ # CRT Browser Testing Reference
4
+
5
+ Use `agentia testing browser` (and the matching `agentia_testing_browser_*` MCP tools) to drive an interactive Copado Robotic Testing browser session tied to a CRT Job and Project.
6
+
7
+ ## Mental Model
8
+
9
+ - **One active session at a time**, stored in `.agentia/config.user.json` under `testingBrowserSession`. Always pass `--project <project-id>` (and optional `<job-id>` / `--session-id` guards).
10
+ - **In-memory Session Cookies**: Agentia exchanges your CRT PAK for `FL`, `XSRF-TOKEN`, and `sessionsToken` cookies via `/user/access-keys/tokens?toSign=all`. Cookies stay in memory (cached with a 60s expiry buffer in long-lived processes like MCP and `recorder`) and are never written to disk.
11
+ - **Browser Viewer**: Always pass `--no-open` to `testing browser view` by default (`agentia testing browser view --project <project-id> --no-open --json`) to print/return the interactive CRT browser session URL `https://<domain>/browser/session/<sessionId>?projectId=<projectId>&orgId=<orgId>` without launching a local browser window. Omit `--no-open` only when the user explicitly asks to open the browser. `testing browser stop` cleans up the session automatically.
12
+ - **Replayable Keyword History**: Every `testing browser execute` and `testing browser recorder` event appends to `~/.agentia/testing-live/<projectId>/<jobId>.jsonl` with full Robot Framework keyword lines (`TypeSecret` values and auth tokens redacted). Closing a session does not clear history.
13
+
14
+ ## Canonical Workflow
15
+
16
+ ```sh
17
+ # 1. Start the session (polls /api/status, loads QWeb/QForce/QMobile, sets QWeb config, opens Chrome)
18
+ agentia testing browser start <job-id> --project <project-id> --json
19
+
20
+ # 2. (Optional) Start the recorder in a background subagent before handing the viewer URL to a user
21
+ agentia testing browser recorder --project <project-id> --output flow.robot
22
+
23
+ # 3. Surface the viewer URL with --no-open by default (omit --no-open only if the user explicitly asks to open the browser)
24
+ agentia testing browser view --project <project-id> --no-open --json
25
+
26
+ # 4. Execute Robot Framework keywords (4+ spaces separate arguments)
27
+ agentia testing browser execute --project <project-id> \
28
+ --line "GoTo https://example.com" \
29
+ --line "VerifyText Example Domain" --json
30
+
31
+ # 5. Observe page state, DOM, and annotated screenshots
32
+ agentia testing browser inspect --project <project-id> --json
33
+ agentia testing browser inspect --project <project-id> --dom --json
34
+ agentia testing browser screenshot --project <project-id> --output /tmp/page.png --json
35
+
36
+ # 6. Export proven steps from Keyword History into a .robot script
37
+ agentia testing browser history <job-id> --project <project-id> --lines-only > flow.robot
38
+
39
+ # 7. Tear down the session (cleans up host, PACE, and local state)
40
+ agentia testing browser stop --project <project-id> --yes --json
41
+ ```
42
+
43
+ ## Subcommands & Flags
44
+
45
+ | Subcommand | Purpose & Key Flags |
46
+ | --- | --- |
47
+ | `testing browser start <job-id>` | Create and bootstrap a session. Flags: `--project` (required), `--library QWeb\|QForce\|QMobile` (default `QWeb`), `--no-bootstrap`, `--no-browser`, `--screen WIDTHxHEIGHTxDEPTH`, `--viewport WIDTHxHEIGHT`, `--file`, `--timeout`. |
48
+ | `testing browser status [job-id]` | Check `env` (`isBrowserStarted`, `isWindowOpen`), `recorder` (`connected`), `server` (`ambleApiVersion`, `inShutdownState`, `inFatalErrorState`), and `session` (`currentIdleTime`, `sessionIdleTimeout`, `timeToExpire`, `isKeywordExecutionPending`). |
49
+ | `testing browser execute [job-id]` | Run keywords using `--line "..."` (repeatable), `--keyword <name> --arg <val>`, `--file <path>`, or `--stdin`. Pass `--raw` to skip `.robot` section parsing. |
50
+ | `testing browser inspect [job-id]` | Fetch `GET /api/system-state` (`url`, `timestamp`, `changeOrigin`, `systemState` interactive element annotations). Add `--dom` with `--output <file>` or `--json` to stream and reassemble `document.documentElement.outerHTML` over the terminal WebSocket. |
51
+ | `testing browser screenshot [job-id]` | Save the current viewport PNG (including teal detection bounding boxes) to `--output <path>`. |
52
+ | `testing browser set-options [job-id]` | Set the full recorder option block (`--[no-]enable`, `--[no-]scroll-text`, `--[no-]healing-context`, `--[no-]hover-text`, `--[no-]system-state`, `--[no-]verify-text`, `--[no-]table-keywords`). Unspecified options default to `false`. |
53
+ | `testing browser view` | Print (`--no-open`, default for agents) or open the CRT browser session URL. Always use `--no-open` unless the user explicitly asks to open the browser. |
54
+ | `testing browser recorder [job-id]` | Connect to the session WebSocket, enable backend recording, and stream captured interactions and executed keywords as Robot Framework lines (or JSON lines with `--json`). Flags: `--output <file.robot>`, `--no-enable`, `--force` (reclaim stale lock), `--debug`. |
55
+ | `testing browser history [job-id]` | Read per-job keyword history. Flags: `--job <id>`, `--limit <n>`, `--keyword <name>` (case-insensitive first token), `--lines-only` (flatten to raw `.robot` lines), `--include-failed` (failed executions are omitted by default), `--status completed\|failed\|recorded`. MCP `linesOnly: true` returns `count`, `jobId`, `lines`, and `projectId` without `executions`. |
56
+ | `testing browser stop [job-id]` | Stop the session on the session host and PACE, and clear local state. Requires `--yes` in `--json` / non-TTY mode (`confirm: true` in MCP). |
57
+
58
+ ## Parallel Recorder & Idle Keepalive Patterns
59
+
60
+ ### 1. Parallel Recorder via Background Subagent
61
+ When driving or co-piloting a browser session with a human:
62
+ 1. Run `agentia testing browser start <job-id> --project <project-id> --json`.
63
+ 2. Before handing the viewer URL to the user, start `agentia testing browser recorder --project <project-id> --output captured.robot` in a background shell/subagent. The recorder captures both browser interactions (`status: "recorded"`) and `testing browser execute` commands (`status: "completed"`) in execution order so `--output` produces a complete `.robot` file.
64
+ 3. Run `agentia testing browser view --project <project-id> --no-open --json` (always pass `--no-open` by default unless the user explicitly asks to open the browser) and share the `url` with the user.
65
+ 4. **Verify capture after the user's first action**:
66
+ ```sh
67
+ agentia testing browser history --project <project-id> --status recorded --json
68
+ ```
69
+ `recorder.connected: true` in `status` only proves the WebSocket is open, not that events are firing. If `count` remains `0` after the user clicks, drive the steps via `testing browser execute` instead.
70
+ 5. **Clean shutdown**: Send `SIGINT` (`kill -INT <pid>`) to the recorder process before running `testing browser stop` so it cleanly posts `setoptions {recorder: {enabled: false}}`. Then export the unified script from history with `agentia testing browser history --project <project-id> --lines-only > captured.robot`.
71
+
72
+ ### 2. Keeping Idle Sessions Warm (600s Timeout)
73
+ - `session.sessionIdleTimeout` defaults to **600 seconds (10 minutes)** and is reset **only by executed keywords**.
74
+ - The recorder's 3-second WebSocket heartbeat keeps the socket open but **does not reset the session idle timer**.
75
+ - When waiting on a human to log in (e.g., MFA/SSO) or inspect the viewer, run a lightweight keepalive loop that fires `GetTitle` every 4 minutes:
76
+ ```sh
77
+ while true; do sleep 240; agentia testing browser execute --project <project-id> --line "GetTitle" --json || break; done &
78
+ ```
79
+ Stop the keepalive loop before `testing browser stop`.
80
+
81
+ ## Troubleshooting
82
+
83
+ - **`No active CRT browser session`**: Start a session with `agentia testing browser start <job-id> --project <project-id>`. If a session died from the 600s idle timeout (`404` / `410`), Agentia clears the stale local state automatically on `status` or `stop`.
84
+ - **`A CRT browser recorder is already running for session <id>`**: Another recorder holds the owner-scoped lock at `~/.agentia/testing-live/locks/<sessionId>.lock`. Stop the other process or pass `--force` if the prior process crashed.
85
+ - **Keyword fails (`CRT browser keyword execution failed`)**:
86
+ 1. Do not retry blindly. Run `agentia testing browser inspect --project <project-id> --json`.
87
+ 2. Check if the target element has `isCovered: true` (modal/sticky header blocking it) or different `readableTexts`.
88
+ 3. Check `agentia testing browser status --project <project-id> --json` to confirm `env.isWindowOpen: true` and `server.inFatalErrorState: false`.
89
+ - **Browser window closed (`isWindowOpen: false`)**: Re-open Chrome with:
90
+ ```sh
91
+ agentia testing browser execute --project <project-id> --line "Open Browser about:blank chrome" --json
92
+ ```
@@ -0,0 +1,112 @@
1
+ <!-- Agentia managed skill file: agentia setup skills -->
2
+
3
+ # Goal-Driven Flow Automation in CRT Browser Testing
4
+
5
+ Use this methodology when turning a natural-language goal ("create a lead", "add a product to the cart and verify checkout") into a verified sequence of Robot Framework keywords against an active `agentia testing browser` session.
6
+
7
+ Applies to `QWeb` (default), `--library QForce` (see [qforce.md](qforce.md) for Lightning-specific rules layered on top), and `--library QMobile`.
8
+
9
+ ## The Core Loop
10
+
11
+ ```text
12
+ Observe -> Act (one logical step) -> Verify expected state -> Recover if needed -> Continue
13
+ ```
14
+
15
+ Do **not** write an entire multi-page `.robot` script up front and fire it in one `testing browser execute --file` call. Every page transition is a hypothesis until confirmed against the browser session. Execute one logical step at a time, verify the transition, and then choose the next keyword. Batching is only appropriate for coupled inputs on the same verified view (such as `TypeText Username ...` + `TypeSecret Password ...`).
16
+
17
+ ```sh
18
+ # 1. Act
19
+ agentia testing browser execute --project <project-id> --line "GoTo https://example.com" --json
20
+
21
+ # 2. Verify
22
+ agentia testing browser execute --project <project-id> --line "VerifyText Example Domain" --json
23
+
24
+ # 3. Observe interactive elements before the next decision
25
+ agentia testing browser inspect --project <project-id> --json
26
+ ```
27
+
28
+ ## Choosing Locators (Priority Order)
29
+
30
+ Always prefer semantic locators over structural XPaths:
31
+
32
+ 1. **Visible text** (`ClickText`, `TypeText`, `TypeSecret`, `VerifyText`, `DropDown`, `ClickCheckbox`). Disambiguate repeated text with `anchor=<nearby text>` before reaching for `index=<N>`.
33
+ 2. **Unique attribute** (`alt`, `title`, `tooltip`, `data-icon`) when there is no visible text — use `ClickItem` / `VerifyItem`.
34
+ 3. **XPath as a last resort** (`ClickElement`, `VerifyElement`) only when text and attribute locators cannot reach the element.
35
+
36
+ While exploring unfamiliar pages, pass a short bounded timeout (`timeout=3`) so a wrong locator fails in 3 seconds instead of 10 seconds:
37
+
38
+ ```sh
39
+ agentia testing browser execute --project <project-id> --line "ClickText Sign In timeout=3" --json
40
+ ```
41
+
42
+ Drop the tight `timeout=3` override when curating the final exported `.robot` suite.
43
+
44
+ ## Why "Completed" Execution Still Needs Verification
45
+
46
+ `testing browser execute` returning `status: "completed"` only proves the keyword ran without throwing an error—it does **not** prove that navigation succeeded, a form submitted, or a modal opened.
47
+
48
+ After any state-changing keyword (`GoTo`, `Click*`, `Type*`, `DropDown`, `PickList`, `ComboBox`, `PressKey`), run a `Verify*` keyword targeting content **unique to the new state**:
49
+ - After login -> verify dashboard heading or app navigation.
50
+ - After opening a modal -> verify a field label inside the modal before typing.
51
+ - After saving a record -> verify the saved state or record detail field.
52
+
53
+ Watch for missing workflow transitions:
54
+ - **Typed into a search box**: Append `\n` to the `TypeText` value to submit on Enter, or click the search button.
55
+ - **Filled form fields**: Click `Save` / `Submit` before asserting the outcome.
56
+
57
+ ## Observing Page State: `inspect` + `screenshot` Overlay
58
+
59
+ | Question | Command |
60
+ | --- | --- |
61
+ | Which interactive elements are visible? | `agentia testing browser inspect --project <project-id> --json` |
62
+ | What does the viewport look like with detection boxes? | `agentia testing browser screenshot --project <project-id> --output /tmp/page.png --json` |
63
+ | What is the raw HTML (`outerHTML`)? | `agentia testing browser inspect --project <project-id> --dom --json` |
64
+
65
+ ### Reading `inspect` and `screenshot` Together
66
+ The PNG saved by `testing browser screenshot` is not a plain screenshot: the CRT inspection engine draws colored bounding rectangles (teal by default from `SetConfig HighlightColor teal`) around every detected UI element. Each rectangle corresponds to an entry in the `systemState` array from `testing browser inspect`:
67
+ - `annotationIndex` — matches the numbered/boxed element in the detection pass.
68
+ - `readableTexts` (`ownText`, `ariaLabel`, `nearbyTexts`) — exact strings to pass to `ClickText` / `TypeText` and `anchor=`.
69
+ - `elementType` and `role` — distinguishes inputs, buttons, links, and `role="combobox"` lookups.
70
+ - `isVisible`, `isInteractive`, `isEnabled`, `isCovered` — if `isCovered: true`, a modal, toast, or sticky header is covering the element and must be closed or scrolled past first.
71
+
72
+ ## Recovery Protocol
73
+
74
+ When an action or verification fails:
75
+ 1. **Stop immediately.** Do not execute the next planned step.
76
+ 2. **Inspect first** (`testing browser inspect` and `testing browser screenshot`) — never retry blindly.
77
+ 3. **Compare expected vs. actual state**:
78
+ - *Still on the previous view?* A workflow transition (submit, save, menu click) didn't fire. Complete the transition rather than swapping locators.
79
+ - *On the expected view?* The locator was wrong. Pick up to 3 semantic alternatives directly from `systemState[].readableTexts` (`anchor=`, `ClickItem`, etc.).
80
+ 4. **Wrong-but-successful action** (e.g., clicked the wrong `New` button):
81
+ - Inspect where you landed, restore the prior view (`Back` or re-navigate), verify restoration, and retry with `anchor=<nearby text>` or `SetConfig PartialMatch False`.
82
+ - Remember that successful wrong clicks land in `testing browser history` (`status: "completed"`) — strip them when curating the final `.robot` file.
83
+
84
+ ## Tuning the Session for Agent-Driven Flows
85
+
86
+ - **Exact text matching**: Bootstrap sets `PartialMatch True`. On text-dense pages (especially Salesforce Lightning), switch to exact matching since you have exact `readableTexts` from `inspect`:
87
+ ```sh
88
+ agentia testing browser execute --project <project-id> --line "SetConfig PartialMatch False" --json
89
+ ```
90
+ - **XHR-heavy pages**: Raise timeouts with `SetConfig DefaultTimeout 20s` and `SetConfig XHRTimeout 30s` instead of adding `Sleep`.
91
+
92
+ ## Exporting and Promoting the Proven Flow
93
+
94
+ Failed probes (`status: "failed"`) are automatically excluded by `testing browser history`:
95
+
96
+ ```sh
97
+ agentia testing browser history <job-id> --project <project-id> --lines-only > flow.robot
98
+ ```
99
+
100
+ Curate `flow.robot` by removing exploratory detours, temporary `timeout=3` overrides, and duplicate steps, then wrap it in a standard Robot Framework suite for `agentia testing job files upload` and `agentia testing job run`:
101
+
102
+ ```robotframework
103
+ *** Settings ***
104
+ Library QWeb
105
+ Suite Setup Open Browser about:blank chrome
106
+ Suite Teardown Close All Browsers
107
+
108
+ *** Test Cases ***
109
+ Verified Flow
110
+ GoTo https://example.com
111
+ VerifyText Example Domain
112
+ ```
@@ -0,0 +1,88 @@
1
+ <!-- Agentia managed skill file: agentia setup skills -->
2
+
3
+ # QForce & Salesforce Lightning Reference for CRT
4
+
5
+ QForce is Copado Robotic Testing's Salesforce keyword library. It is a superset of [QWeb](qweb.md): all QWeb keywords (`ClickText`, `TypeText`, `VerifyText`, `UseTable`, etc.) work unchanged, and QForce adds Salesforce Lightning-aware locators and keywords on top.
6
+
7
+ To start a Salesforce browser session:
8
+
9
+ ```sh
10
+ agentia testing browser start <job-id> --project <project-id> --library QForce --json
11
+ agentia testing browser execute --project <project-id> --line "SetConfig PartialMatch False" --json
12
+ ```
13
+
14
+ When these Salesforce-specific rules conflict with generic QWeb text-first guidance, **the Salesforce rule wins**.
15
+
16
+ ## Mandatory Salesforce Rules
17
+
18
+ 1. **Always normalize app state with `LaunchApp`**:
19
+ Immediately after login—and before any app-specific click, tab navigation, or assertion—run:
20
+ ```robotframework
21
+ LaunchApp Sales
22
+ ```
23
+ `LaunchApp` is idempotent: it checks the active Lightning app and only opens the App Launcher when needed. Never skip it just because the right app appears open, and do not replace it with manual clicks on the App Launcher waffle icon.
24
+ 2. **Verify Record Details with `VerifyField`, never `VerifyText`**:
25
+ Lightning record pages contain repeated labels in headers, related lists, and activity timelines, causing `VerifyText` to pass for the wrong reason.
26
+ 3. **Three dropdown families require three distinct keywords**:
27
+ - Native HTML `<select>` -> `DropDown <label> <value>`
28
+ - Lightning custom picklist (button/div/listbox widget) -> `PickList <label> <value>`
29
+ - Lookup / searchable combobox (`input` with `role="combobox"`) -> `ComboBox <locator> <value> timeout=10`
30
+ 4. **Lookups (`ComboBox`) only select existing records**:
31
+ Never finish a lookup field with `TypeText` (typed text is not a selected record). If the target record does not exist, use the nested `New <Object>` creation flow.
32
+ 5. **Never hard-code org-specific Lightning URLs or record IDs**:
33
+ Navigate via `LaunchApp` and object tabs so tests survive sandbox refreshes. Store credentials in CRT Variables (`testing variable`) or User Parameters (`testing user-parameter`) and type secrets with `TypeSecret`.
34
+
35
+ ## QForce Keyword Catalog
36
+
37
+ In `.robot` files and `testing browser execute`, always use `KeywordCase` (`LaunchApp`, `VerifyField`, `PickList`, `ComboBox`). Separate arguments with 4+ spaces.
38
+
39
+ | Keyword | Form | When to Use |
40
+ | --- | --- | --- |
41
+ | `LaunchApp` | `LaunchApp <Exact App Name>` | Open a Salesforce Lightning app via the App Launcher by exact name (`Sales`, `Service`). |
42
+ | `VerifyField` | `VerifyField <label> <expected>` | Assert a plain-text field value on a Record Details page (`VerifyField Phone 123456789`). |
43
+ | `VerifyField` (link) | `VerifyField <label> <expected> tag=a` | Assert a linked field value (lookup, owner, related record: `VerifyField Account Name Acme tag=a`). |
44
+ | `VerifyField` (indexed) | `VerifyField <label> <expected> <index> [tag=a]` | Disambiguate when the same field label appears multiple times on the Details page. Discover `<index>` with `GetFieldValue` first. |
45
+ | `GetFieldValue` | `GetFieldValue <label> [index]` | Read the value of the Nth field with `<label>` to discover which index to pass to `VerifyField`. |
46
+ | `PickList` | `PickList <label> <value> [index=1] [timeout=0]` | Select an option from a Lightning custom picklist (`PickList Stage Closed Won`). |
47
+ | `ComboBox` | `ComboBox <locator> <value> timeout=10` | Search and select an **existing** record in a Lightning lookup/combobox (`ComboBox Account Name Acme timeout=10` or `ComboBox Search Accounts... Acme timeout=10`). |
48
+
49
+ ## Record Details Verification Ladder
50
+
51
+ On a Salesforce record's **Details** tab, follow this order:
52
+
53
+ 1. **Plain field**: `VerifyField <label> <expected>`
54
+ 2. **Linked field (lookup/owner)**: `VerifyField <label> <expected> tag=a`
55
+ 3. **Duplicate field label on page**: Probe indexes with `GetFieldValue`, then assert with indexed `VerifyField`:
56
+ ```robotframework
57
+ GetFieldValue Account Name 1
58
+ GetFieldValue Account Name 2
59
+ VerifyField Account Name Acme Corp 2 tag=a
60
+ ```
61
+ 4. **Never use `VerifyText` as the primary Details assertion**, and do not assert on ephemeral toast messages (toasts vanish quickly; verify the saved record's Details instead).
62
+
63
+ ## Lookup Fields & Nested Record Creation
64
+
65
+ When filling a lookup field (such as `Account Name` on a Contact or Opportunity):
66
+
67
+ - **If the target record exists**:
68
+ ```robotframework
69
+ ComboBox Account Name Acme Corp timeout=10
70
+ ClickText Save
71
+ ClickText Details
72
+ VerifyField Account Name Acme Corp tag=a
73
+ ```
74
+ - **If `ComboBox` fails (`Could not find combobox ... with value ...`) or the record does not exist**:
75
+ Do not retry `ComboBox` in a loop and do not leave raw `TypeText` in the input. Trigger the nested `New <Object>` modal from the lookup instead:
76
+ ```robotframework
77
+ ClickText Account Name
78
+ ClickText New Account
79
+ TypeText Account Name Acme Corp
80
+ ClickText Save
81
+ ```
82
+
83
+ ## Recognising Dropdown Types via `testing browser inspect`
84
+
85
+ When unsure whether a field uses `DropDown`, `PickList`, or `ComboBox`, run `agentia testing browser inspect --project <project-id> --json` and check the element in `systemState`:
86
+ - `elementType: "select"` -> `DropDown`
87
+ - Clickable button/div showing the current picklist value (not an `input`) -> `PickList`
88
+ - `elementType: "input"` with `role: "combobox"` or placeholder `Search ...` -> `ComboBox`
@@ -0,0 +1,103 @@
1
+ <!-- Agentia managed skill file: agentia setup skills -->
2
+
3
+ # QWeb Keyword Reference for CRT
4
+
5
+ QWeb is the web-automation Robot Framework library used by Copado Robotic Testing in `.robot` suites (`agentia testing job run`) and browser sessions (`agentia testing browser start <job-id> --project <project-id>`).
6
+
7
+ For goal-driven exploration in a browser session, pair this reference with [flow-automation.md](flow-automation.md). For Salesforce Lightning, also load [qforce.md](qforce.md).
8
+
9
+ ## Syntax & Formatting Rules
10
+
11
+ - **4+ space separator**: Separate the keyword name, positional arguments, and `key=value` named arguments with **at least 4 spaces** (`KeywordName arg1 arg2 anchor=Header`). Never use a single space—Robot Framework treats `ClickText Login` as a single nonexistent keyword name.
12
+ - **Prefer visible text over XPath**: `PartialMatch` is `True` by default in browser sessions (`SetConfig PartialMatch False` forces exact matches).
13
+ - **`anchor=<text>` for disambiguation**: When the same text appears multiple times, pass `anchor=<nearby text>` (`ClickText Edit anchor=Profile`). Use 1-based `index=<N>` only as a last resort.
14
+ - **Booleans**: Capitalize `True` and `False` (`clear=False`, `partial_match=False`).
15
+ - **Submitting on Enter**: Append `\n` to `TypeText` (`TypeText Search laptop\n`) or run `PressKey ${EMPTY} {ENTER}`.
16
+ - **XPath `=` escaping**: In browser testing (`testing browser execute`), Agentia automatically escapes `=` inside `//...` XPath tokens so Robot Framework does not misread `@id="x"` as a named parameter.
17
+
18
+ ## Keyword Catalog
19
+
20
+ ### Navigation
21
+
22
+ | Keyword | Form | Notes |
23
+ | --- | --- | --- |
24
+ | `GoTo` | `GoTo https://example.com` | Navigate to a full URL (`https://...`). |
25
+ | `Back` / `Forward` | `Back` | Browser history navigation. |
26
+ | `RefreshPage` | `RefreshPage` | Reload the current page. |
27
+ | `Open Browser` | `Open Browser about:blank chrome` | Suite setup; already executed during `testing browser start` unless `--no-browser` is passed. |
28
+ | `Close All Browsers` | `Close All Browsers` | Suite teardown. Do not call during an active browser session; use `testing browser stop` instead. |
29
+
30
+ ### Clicking
31
+
32
+ | Keyword | Form | When to Use |
33
+ | --- | --- | --- |
34
+ | `ClickText` | `ClickText <text> [anchor=<text>]` | Default choice for any button, link, or tab with visible text. |
35
+ | `ClickItem` | `ClickItem <alt_or_title> [anchor=<text>]` | Click by `alt`, `title`, `tooltip`, `data-tooltip`, or `data-icon` (ideal for icon-only buttons). |
36
+ | `ClickElement` | `ClickElement <xpath>` | Last resort when neither `ClickText` nor `ClickItem` can target the element. |
37
+ | `ClickCheckbox` | `ClickCheckbox <label> on\|off` | Idempotently set a checkbox to `on` or `off`. |
38
+ | `ClickList` | `ClickList <list_locator> <item_text>` | Click an item inside a list widget. |
39
+ | `ClickCell` | `ClickCell <row> <col>` | Click a cell inside the active table (requires `UseTable` first). |
40
+
41
+ ### Typing & Form Inputs
42
+
43
+ | Keyword | Form | Notes |
44
+ | --- | --- | --- |
45
+ | `TypeText` | `TypeText <label> <value> [clear=False]` | Clears the field and types `<value>`. Append `\n` to submit. |
46
+ | `TypeSecret` | `TypeSecret <label> <value>` | Same as `TypeText`, but masks the value in logs and Agentia browser history. |
47
+ | `DropDown` | `DropDown <label> <option>` | Select an option from a native HTML `<select>` element. |
48
+ | `GetInputValue` | `GetInputValue <label>` | Read the current value of an input field. |
49
+
50
+ ### Verification & Reading
51
+
52
+ | Keyword | Form | Notes |
53
+ | --- | --- | --- |
54
+ | `VerifyText` | `VerifyText <text> [timeout=30]` | Assert visible text appears on the page (preferred over `Sleep` for waiting). |
55
+ | `VerifyNoText` | `VerifyNoText <text> [timeout=10]` | Assert text does not appear (or disappears). |
56
+ | `VerifyItem` | `VerifyItem <alt_or_title>` | Assert an element with the given `alt`/`title`/`tooltip` exists. |
57
+ | `VerifyElement` | `VerifyElement <xpath> [timeout=30]` | Assert an XPath exists in the DOM. |
58
+ | `VerifyValue` | `VerifyValue <label> <expected>` | Assert an input field holds `<expected>`. |
59
+ | `VerifyCheckboxValue` | `VerifyCheckboxValue <label> on\|off` | Assert a checkbox state. |
60
+ | `GetText` | `GetText <locator>` | Read visible text of an element. |
61
+ | `GetAttribute` | `GetAttribute <locator> <attribute>` | Read an attribute (e.g., `href`, `aria-expanded`, `outerHTML`). |
62
+ | `GetTitle` | `GetTitle` | Read the document title (also useful as a harmless keepalive keyword in browser sessions). |
63
+
64
+ ### Hover, Scroll, Drag & Keyboard
65
+
66
+ | Keyword | Form | Notes |
67
+ | --- | --- | --- |
68
+ | `HoverText` / `HoverElement` | `HoverText <text>` | Hover over an element to reveal menus or tooltips. |
69
+ | `Scroll` | `Scroll <locator> page_down\|page_up\|<px>` | Scroll an element or `//html` for the full page. |
70
+ | `ScrollTo` | `ScrollTo <text_locator>` | Scroll until `<text_locator>` is in view. |
71
+ | `DragDrop` | `DragDrop <source> <target>` | Drag one element onto another. |
72
+ | `PressKey` | `PressKey <locator> <key>` | Use `${EMPTY}` for global key press (`{ENTER}`, `{ESC}`, `{TAB}`). |
73
+
74
+ ### Stateful Tables
75
+
76
+ Call `UseTable` once to bind the active table, then address cells by 1-based row/column (`r1`, `c2`) or header/row text:
77
+
78
+ ```robotframework
79
+ UseTable Users
80
+ ClickCell r1 Email
81
+ VerifyTable r1 Status Active
82
+ ```
83
+
84
+ ### Configuration (`SetConfig`)
85
+
86
+ | Setting | Example | Purpose |
87
+ | --- | --- | --- |
88
+ | `DefaultTimeout` | `SetConfig DefaultTimeout 20s` | Global auto-wait timeout for locators (default `10s`). |
89
+ | `XHRTimeout` | `SetConfig XHRTimeout 30s` | Wait for pending XHR/network activity before acting. |
90
+ | `PartialMatch` | `SetConfig PartialMatch False` | Require exact text matches instead of substring matches. |
91
+ | `CaseInsensitive` | `SetConfig CaseInsensitive True` | Enable case-insensitive text matching. |
92
+ | `ClickToFocus` | `SetConfig ClickToFocus True` | Click inputs before typing (enabled by default in browser sessions). |
93
+
94
+ ## Decision Tree
95
+
96
+ 1. **Open a URL** -> `GoTo https://...`
97
+ 2. **Click readable text** -> `ClickText <text>` (add `anchor=<nearby>` if repeated)
98
+ 3. **Click an icon/image with no text** -> `ClickItem <alt_or_title>`, else `ClickElement <xpath>`
99
+ 4. **Type into a field** -> `TypeText <label> <value>` (or `TypeSecret` for passwords/tokens)
100
+ 5. **Select from a native `<select>`** -> `DropDown <label> <option>`
101
+ 6. **Toggle a checkbox** -> `ClickCheckbox <label> on`
102
+ 7. **Wait for page readiness** -> `VerifyText <landmark> timeout=30` (avoid `Sleep`)
103
+ 8. **Work with a table** -> `UseTable <table_name>` -> `VerifyTable` / `ClickCell`
@@ -46,7 +46,7 @@ agentia testing job runs logs <build-id> --project <project-id> --job <job-id> -
46
46
  | Variables | `testing variable list|get|create|update|delete` |
47
47
  | User parameters | `testing user-parameter list|get|create|update|delete` |
48
48
  | Data tables | `testing data-table list|get|create|update|delete|export` |
49
- | Live testing | `testing live start|stop|status|execute|continue|interrupt|inspect|screenshot|reports|set-options|history|view|recorder` |
49
+ | Browser testing | `testing browser start|stop|status|execute|inspect|screenshot|set-options|history|view|recorder` |
50
50
 
51
51
  `testing job` is the single namespace for test definitions and their runs. Commands directly under `job` take a job ID; `job runs get|logs|abort` take a build/run ID plus `--job`. On `testing job create` and `testing job update`, `--[no-]show-video-params` (`showVideoParams` in the API/MCP) enables or disables Video Streaming and Recording capabilities when running the test job. The older `testing create|update|status|logs|run`, `testing test ...`, `testing build ...`, and `testing job files|upload|download` forms are deprecated aliases that still execute but warn when used: `create` maps to `job create`, `update` to `job files upload` (file operations, not `job update`), `status`, `build list`, and `build latest` to `job runs list`, `build get` to `job runs get`, and `build search|logs|abort` to `job runs search|logs|abort`.
52
52
 
@@ -65,19 +65,27 @@ Schedules support get, set with cron/timezone/record policy, and remove. Data ta
65
65
 
66
66
  Data-table create/update/delete and existing-file overwrite are protected operations. Never overwrite or delete without user intent.
67
67
 
68
- ## Live Testing
68
+ ## Browser Testing
69
69
 
70
70
  Use a regression-owned job:
71
71
 
72
72
  ```sh
73
- agentia testing live start <job-id> --project <project-id> --json
74
- agentia testing live status --project <project-id> --json
75
- agentia testing live execute --project <project-id> --line "GoTo https://example.com" --json
76
- agentia testing live inspect --project <project-id> --json
77
- agentia testing live stop --project <project-id> --yes --json
73
+ agentia testing browser start <job-id> --project <project-id> --json
74
+ agentia testing browser status --project <project-id> --json
75
+ agentia testing browser view --project <project-id> --no-open --json
76
+ agentia testing browser execute --project <project-id> --line "GoTo https://example.com" --json
77
+ agentia testing browser inspect --project <project-id> --json
78
+ agentia testing browser history <job-id> --project <project-id> --lines-only
79
+ agentia testing browser stop --project <project-id> --yes --json
78
80
  ```
79
81
 
80
- Live viewer secrets remain in the keychain. Session cookies and XSRF values are in-memory only. `view` opens an authenticated page without putting secrets in the URL. `recorder` is long-running and uses an owner-scoped local lock; neither `view` nor `recorder` is exposed through MCP.
82
+ Always pass `--no-open` to `testing browser view` by default to print/return the interactive CRT browser session URL without launching a browser; omit `--no-open` only when the user explicitly asks to open the browser. Session cookies and XSRF values remain in-memory only. `recorder` is long-running and uses an owner-scoped local lock (`--force` reclaims a stale lock); neither `view` nor `recorder` is exposed through MCP. The older `testing live ...` commands remain available as deprecated aliases, except `continue` and `interrupt`, which were removed.
83
+
84
+ For deep browser-testing guidance, load:
85
+ - [browser-testing.md](browser-testing.md) — subcommands, flags, parallel recorder subagent pattern, 600s idle keepalive, and troubleshooting
86
+ - [flow-automation.md](flow-automation.md) — Observe -> Act -> Verify -> Recover loop and reading `screenshot` detection overlays with `inspect` `systemState`
87
+ - [qweb.md](qweb.md) — QWeb keyword catalog, 4+ space separator rule, and locator priority
88
+ - [qforce.md](qforce.md) — Salesforce Lightning rules (`--library QForce`, `LaunchApp`, `VerifyField`, `PickList`, `ComboBox`)
81
89
 
82
90
  ## Secret Inputs And Redaction
83
91
 
@@ -90,7 +98,7 @@ Live viewer secrets remain in the keychain. Session cookies and XSRF values are
90
98
 
91
99
  Destructive or protected CLI actions prompt in an interactive TTY. JSON and non-TTY calls require `--yes`. Matching MCP tools require `confirm: true`, not a `yes` field.
92
100
 
93
- This applies to resource deletion, build abort, schedule removal, live stop, protected data-table imports/deletion, and output overwrite.
101
+ This applies to resource deletion, build abort, schedule removal, browser stop, protected data-table imports/deletion, and output overwrite.
94
102
 
95
103
  ## Gotchas
96
104
 
Binary file
@@ -1,16 +0,0 @@
1
- import { AgentiaCommand } from '../../../lib/agentia-command.js';
2
- import { runTestingLiveControlCommand, testingLiveCommonFlags, testingLiveOptionalJobArg, } from '../../../lib/testing-live-command.js';
3
- export default class TestingLiveContinue extends AgentiaCommand {
4
- static args = testingLiveOptionalJobArg;
5
- static description = 'Continue paused Robot execution in the active CRT live session';
6
- static examples = ['<%= config.bin %> <%= command.id %> --project <project-id>'];
7
- static flags = testingLiveCommonFlags;
8
- async run() {
9
- const { args, flags } = await this.parse(TestingLiveContinue);
10
- return runTestingLiveControlCommand('continue', args, flags, {
11
- display: (fn) => this.display(fn),
12
- log: (msg) => this.log(msg),
13
- });
14
- }
15
- }
16
- //# sourceMappingURL=continue.js.map
@@ -1,43 +0,0 @@
1
- import { Flags } from '@oclif/core';
2
- import { AgentiaCommand } from '../../../lib/agentia-command.js';
3
- import { testingLiveCommonFlags, testingLiveOptionalJobArg } from '../../../lib/testing-live-command.js';
4
- import { executeTestingLive } from '../../../lib/testing-live-operations.js';
5
- export default class TestingLiveExecute extends AgentiaCommand {
6
- static args = testingLiveOptionalJobArg;
7
- static description = 'Execute bounded Robot Framework keywords in an active CRT live session';
8
- static examples = [
9
- '<%= config.bin %> <%= command.id %> --project <project-id> --keyword GoTo --arg https://example.com',
10
- '<%= config.bin %> <%= command.id %> <job-id> --project <project-id> --file smoke.robot --section Login',
11
- ];
12
- static flags = {
13
- ...testingLiveCommonFlags,
14
- arg: Flags.string({ description: 'Keyword argument. Repeat to preserve argument boundaries.', multiple: true }),
15
- file: Flags.string({ description: 'Robot Framework input file.' }),
16
- keyword: Flags.string({ description: 'Robot Framework keyword name.' }),
17
- line: Flags.string({ description: 'Raw Robot Framework keyword line. Repeat for multiple lines.', multiple: true }),
18
- raw: Flags.boolean({ default: false, description: 'Treat file input as raw keyword lines.' }),
19
- section: Flags.string({ description: 'Robot test/task name to execute.' }),
20
- 'section-index': Flags.integer({ description: 'One-based Robot test/task index to execute.', min: 1 }),
21
- };
22
- async run() {
23
- const { args, flags } = await this.parse(TestingLiveExecute);
24
- const supplied = [flags.keyword !== undefined, flags.file !== undefined, (flags.line?.length ?? 0) > 0].filter(Boolean);
25
- if (supplied.length !== 1)
26
- throw new Error('Use exactly one of --keyword, --line, or --file.');
27
- const result = await this.withSpinner('Executing CRT live keyword', () => executeTestingLive({
28
- args: flags.arg,
29
- file: flags.file,
30
- jobId: args['job-id'],
31
- keyword: flags.keyword,
32
- lines: flags.line,
33
- projectId: flags.project,
34
- raw: flags.raw,
35
- section: flags.section,
36
- sectionIndex: flags['section-index'],
37
- sessionId: flags['session-id'],
38
- }));
39
- this.display(() => this.log(`Execution ${result.executionId}: ${result.status}`));
40
- return result;
41
- }
42
- }
43
- //# sourceMappingURL=execute.js.map
@@ -1,40 +0,0 @@
1
- import { Args, Flags } from '@oclif/core';
2
- import { AgentiaCommand } from '../../../lib/agentia-command.js';
3
- import { testingLiveCommonFlags } from '../../../lib/testing-live-command.js';
4
- import { getTestingLiveHistory } from '../../../lib/testing-live-operations.js';
5
- import { readTestingLiveState } from '../../../lib/testing-live-state.js';
6
- export default class TestingLiveHistory extends AgentiaCommand {
7
- static args = {
8
- 'job-id': Args.integer({ description: 'CRT job ID; defaults to the active session.', required: false }),
9
- };
10
- static description = 'Read bounded sanitized local CRT live execution history';
11
- static examples = ['<%= config.bin %> <%= command.id %> <job-id> --project <project-id> --limit 20 --json'];
12
- static flags = {
13
- ...testingLiveCommonFlags,
14
- limit: Flags.integer({ default: 10, description: 'Maximum records to return.', max: 500, min: 1 }),
15
- status: Flags.option({
16
- description: 'Execution status filter.',
17
- options: ['completed', 'failed', 'recorded'],
18
- })(),
19
- };
20
- async run() {
21
- const { args, flags } = await this.parse(TestingLiveHistory);
22
- const active = args['job-id'] === undefined ? await readTestingLiveState() : undefined;
23
- const jobId = args['job-id'] ?? active?.jobId;
24
- if (jobId === undefined || (active !== undefined && active.projectId !== flags.project)) {
25
- throw new Error('Provide a job ID or start a live session for this project.');
26
- }
27
- const result = getTestingLiveHistory({
28
- jobId,
29
- limit: flags.limit,
30
- projectId: flags.project,
31
- status: flags.status,
32
- });
33
- this.display(() => {
34
- for (const execution of result.executions)
35
- this.log(`${execution.startedAt} [${execution.status}] ${execution.lines.join(' | ')}`);
36
- });
37
- return result;
38
- }
39
- }
40
- //# sourceMappingURL=history.js.map
@@ -1,31 +0,0 @@
1
- import { Flags } from '@oclif/core';
2
- import { AgentiaCommand } from '../../../lib/agentia-command.js';
3
- import { testingLiveCommonFlags, testingLiveOptionalJobArg } from '../../../lib/testing-live-command.js';
4
- import { inspectTestingLive } from '../../../lib/testing-live-operations.js';
5
- import { formatTestingRecord } from '../../../lib/testing-types.js';
6
- export default class TestingLiveInspect extends AgentiaCommand {
7
- static args = testingLiveOptionalJobArg;
8
- static description = 'Inspect bounded, sanitized page state from an active CRT live session';
9
- static examples = [
10
- '<%= config.bin %> <%= command.id %> --project <project-id> --json',
11
- '<%= config.bin %> <%= command.id %> --project <project-id> --dom --output page.html',
12
- ];
13
- static flags = {
14
- ...testingLiveCommonFlags,
15
- dom: Flags.boolean({ default: false, description: 'Fetch raw page DOM; requires --output.' }),
16
- output: Flags.string({ dependsOn: ['dom'], description: 'Explicit file path for raw DOM.' }),
17
- };
18
- async run() {
19
- const { args, flags } = await this.parse(TestingLiveInspect);
20
- const result = await this.withSpinner('Inspecting CRT live session', () => inspectTestingLive({
21
- dom: flags.dom,
22
- jobId: args['job-id'],
23
- output: flags.output,
24
- projectId: flags.project,
25
- sessionId: flags['session-id'],
26
- }));
27
- this.display(() => this.log(flags.dom ? `DOM written to ${String(result.path)}.` : formatTestingRecord(result)));
28
- return result;
29
- }
30
- }
31
- //# sourceMappingURL=inspect.js.map
@@ -1,16 +0,0 @@
1
- import { AgentiaCommand } from '../../../lib/agentia-command.js';
2
- import { runTestingLiveControlCommand, testingLiveCommonFlags, testingLiveOptionalJobArg, } from '../../../lib/testing-live-command.js';
3
- export default class TestingLiveInterrupt extends AgentiaCommand {
4
- static args = testingLiveOptionalJobArg;
5
- static description = 'Interrupt Robot execution in the active CRT live session';
6
- static examples = ['<%= config.bin %> <%= command.id %> --project <project-id>'];
7
- static flags = testingLiveCommonFlags;
8
- async run() {
9
- const { args, flags } = await this.parse(TestingLiveInterrupt);
10
- return runTestingLiveControlCommand('interrupt', args, flags, {
11
- display: (fn) => this.display(fn),
12
- log: (msg) => this.log(msg),
13
- });
14
- }
15
- }
16
- //# sourceMappingURL=interrupt.js.map