@copado/agentia-cli 1.2.0 → 1.3.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.
- package/CHANGELOG.md +30 -1
- package/README.md +2205 -1530
- package/dist/commands/auth/get.js +21 -1
- package/dist/commands/auth/set.js +13 -0
- package/dist/commands/auth/unset.js +37 -0
- package/dist/commands/cicd/cloud/commit.js +2 -2
- package/dist/commands/cicd/cloud/promote.js +19 -5
- package/dist/commands/cicd/credential/auth/status.js +2 -2
- package/dist/commands/cicd/credential/auth/web/login.js +2 -2
- package/dist/commands/cicd/credential/create.js +2 -2
- package/dist/commands/cicd/credential/list.js +2 -2
- package/dist/commands/cicd/credential/open.js +2 -2
- package/dist/commands/cicd/credential/update.js +2 -2
- package/dist/commands/cicd/data/commit/create.js +2 -2
- package/dist/commands/cicd/data/commit/list.js +2 -2
- package/dist/commands/cicd/data/dataset-file/content.js +2 -2
- package/dist/commands/cicd/data/dataset-file/list.js +2 -2
- package/dist/commands/cicd/data/filter/add.js +2 -2
- package/dist/commands/cicd/data/filter/delete.js +2 -2
- package/dist/commands/cicd/data/filter/list.js +2 -2
- package/dist/commands/cicd/data/filter/update.js +2 -2
- package/dist/commands/cicd/data/formula/create.js +2 -2
- package/dist/commands/cicd/data/formula/list.js +2 -2
- package/dist/commands/cicd/data/formula/update.js +2 -2
- package/dist/commands/cicd/data/records/match.js +2 -2
- package/dist/commands/cicd/data/records/search.js +2 -2
- package/dist/commands/cicd/data/sobject/fields.js +2 -2
- package/dist/commands/cicd/data/sobject/relationships.js +2 -2
- package/dist/commands/cicd/data/sync/apply.js +2 -2
- package/dist/commands/cicd/data/sync/preview-updates.js +2 -2
- package/dist/commands/cicd/data/template/convert-old.js +2 -2
- package/dist/commands/cicd/data/template/create.js +2 -2
- package/dist/commands/cicd/data/template/delete.js +2 -2
- package/dist/commands/cicd/data/template/get-detail.js +2 -2
- package/dist/commands/cicd/data/template/get.js +2 -2
- package/dist/commands/cicd/data/template/list.js +2 -2
- package/dist/commands/cicd/data/template/open.js +2 -2
- package/dist/commands/cicd/data/template/save-detail.js +2 -2
- package/dist/commands/cicd/environment/auth/status.js +2 -2
- package/dist/commands/cicd/environment/auth/web/login.js +2 -2
- package/dist/commands/cicd/environment/create.js +2 -2
- package/dist/commands/cicd/environment/get.js +2 -2
- package/dist/commands/cicd/environment/list.js +2 -2
- package/dist/commands/cicd/environment/open.js +2 -2
- package/dist/commands/cicd/environment/update.js +2 -2
- package/dist/commands/cicd/extension/create.js +2 -2
- package/dist/commands/cicd/extension/install.js +2 -2
- package/dist/commands/cicd/extension/package.js +2 -2
- package/dist/commands/cicd/extension/publish.js +2 -2
- package/dist/commands/cicd/extension/uninstall.js +2 -2
- package/dist/commands/cicd/extension/validate.js +2 -2
- package/dist/commands/cicd/extension-configuration/get.js +2 -2
- package/dist/commands/cicd/extension-configuration/list.js +2 -2
- package/dist/commands/cicd/extension-configuration/open.js +2 -2
- package/dist/commands/cicd/function/defaults.js +2 -2
- package/dist/commands/cicd/function/delete.js +2 -2
- package/dist/commands/cicd/function/get.js +2 -2
- package/dist/commands/cicd/function/list.js +2 -2
- package/dist/commands/cicd/function/open.js +2 -2
- package/dist/commands/cicd/function/result/get.js +2 -2
- package/dist/commands/cicd/function/result/log/get.js +2 -2
- package/dist/commands/cicd/function/run-local.js +2 -2
- package/dist/commands/cicd/function/run.js +2 -2
- package/dist/commands/cicd/function/upsert.js +2 -2
- package/dist/commands/cicd/health-check.js +2 -2
- package/dist/commands/cicd/job/get.js +2 -2
- package/dist/commands/cicd/job/kill.js +2 -2
- package/dist/commands/cicd/job/list.js +2 -2
- package/dist/commands/cicd/job/log/get.js +2 -2
- package/dist/commands/cicd/job/open.js +2 -2
- package/dist/commands/cicd/job/pause.js +2 -2
- package/dist/commands/cicd/job/result-file/get.js +2 -2
- package/dist/commands/cicd/job/result-file/list.js +2 -2
- package/dist/commands/cicd/job/resume.js +2 -2
- package/dist/commands/cicd/job/run.js +2 -2
- package/dist/commands/cicd/metadata/content/compare.js +2 -2
- package/dist/commands/cicd/metadata/content/get.js +2 -2
- package/dist/commands/cicd/metadata/dependency/list.js +44 -21
- package/dist/commands/cicd/metadata/explore.js +2 -2
- package/dist/commands/cicd/metadata/index/compare.js +2 -2
- package/dist/commands/cicd/metadata/list.js +2 -2
- package/dist/commands/cicd/metadata/refresh/deleted.js +2 -2
- package/dist/commands/cicd/metadata/refresh/run.js +2 -2
- package/dist/commands/cicd/metadata/refresh/status.js +2 -2
- package/dist/commands/cicd/notification/configure.js +2 -2
- package/dist/commands/cicd/notification/get.js +2 -2
- package/dist/commands/cicd/pipeline/automation/activate.js +2 -2
- package/dist/commands/cicd/pipeline/automation/create.js +2 -2
- package/dist/commands/cicd/pipeline/automation/deactivate.js +2 -2
- package/dist/commands/cicd/pipeline/automation/delete.js +2 -2
- package/dist/commands/cicd/pipeline/automation/get.js +2 -2
- package/dist/commands/cicd/pipeline/automation/list.js +2 -2
- package/dist/commands/cicd/pipeline/automation/open.js +2 -2
- package/dist/commands/cicd/pipeline/automation/update.js +2 -2
- package/dist/commands/cicd/pipeline/connection/create.js +2 -2
- package/dist/commands/cicd/pipeline/connection/delete.js +2 -2
- package/dist/commands/cicd/pipeline/connection/list.js +2 -2
- package/dist/commands/cicd/pipeline/connection/open.js +2 -2
- package/dist/commands/cicd/pipeline/connection/update.js +2 -2
- package/dist/commands/cicd/pipeline/create.js +2 -2
- package/dist/commands/cicd/pipeline/get.js +2 -2
- package/dist/commands/cicd/pipeline/list.js +2 -2
- package/dist/commands/cicd/pipeline/open.js +2 -2
- package/dist/commands/cicd/pipeline/quality-gate/activate.js +2 -2
- package/dist/commands/cicd/pipeline/quality-gate/create.js +2 -2
- package/dist/commands/cicd/pipeline/quality-gate/deactivate.js +2 -2
- package/dist/commands/cicd/pipeline/quality-gate/delete.js +2 -2
- package/dist/commands/cicd/pipeline/quality-gate/get.js +2 -2
- package/dist/commands/cicd/pipeline/quality-gate/list.js +2 -2
- package/dist/commands/cicd/pipeline/quality-gate/open.js +2 -2
- package/dist/commands/cicd/pipeline/quality-gate/update.js +2 -2
- package/dist/commands/cicd/pipeline/stage-connection/create.js +2 -2
- package/dist/commands/cicd/pipeline/stage-connection/delete.js +2 -2
- package/dist/commands/cicd/pipeline/stage-connection/list.js +2 -2
- package/dist/commands/cicd/pipeline/stage-connection/open.js +2 -2
- package/dist/commands/cicd/pipeline/stage-connection/update.js +2 -2
- package/dist/commands/cicd/pipeline/update.js +2 -2
- package/dist/commands/cicd/project/create.js +2 -2
- package/dist/commands/cicd/project/default/get.js +2 -2
- package/dist/commands/cicd/project/default/set.js +2 -2
- package/dist/commands/cicd/project/default/unset.js +2 -2
- package/dist/commands/cicd/project/delete.js +2 -2
- package/dist/commands/cicd/project/get.js +2 -2
- package/dist/commands/cicd/project/list.js +2 -2
- package/dist/commands/cicd/project/open.js +2 -2
- package/dist/commands/cicd/project/update.js +2 -2
- package/dist/commands/cicd/promotion/conflict/get.js +2 -2
- package/dist/commands/cicd/promotion/conflict/list.js +2 -2
- package/dist/commands/cicd/promotion/conflict/resolve.js +2 -2
- package/dist/commands/cicd/promotion/conflict/unresolve.js +2 -2
- package/dist/commands/cicd/promotion/get.js +2 -2
- package/dist/commands/cicd/promotion/job-step/update.js +2 -2
- package/dist/commands/cicd/promotion/list.js +2 -2
- package/dist/commands/cicd/promotion/open.js +2 -2
- package/dist/commands/cicd/promotion/queue/list.js +28 -0
- package/dist/commands/cicd/promotion/queue/remove.js +37 -0
- package/dist/commands/cicd/promotion/run.js +2 -2
- package/dist/commands/cicd/repository/auth/https/configure.js +2 -2
- package/dist/commands/cicd/repository/auth/oauth/login.js +2 -2
- package/dist/commands/cicd/repository/auth/setup.js +2 -2
- package/dist/commands/cicd/repository/auth/ssh/configure.js +2 -2
- package/dist/commands/cicd/repository/create.js +2 -2
- package/dist/commands/cicd/repository/delete.js +2 -2
- package/dist/commands/cicd/repository/get.js +2 -2
- package/dist/commands/cicd/repository/list.js +2 -2
- package/dist/commands/cicd/repository/open.js +2 -2
- package/dist/commands/cicd/repository/reset.js +2 -2
- package/dist/commands/cicd/repository/update.js +2 -2
- package/dist/commands/cicd/repository/validate.js +2 -2
- package/dist/commands/cicd/stage/create.js +2 -2
- package/dist/commands/cicd/stage/delete.js +2 -2
- package/dist/commands/cicd/stage/get.js +2 -2
- package/dist/commands/cicd/stage/list.js +2 -2
- package/dist/commands/cicd/stage/open.js +2 -2
- package/dist/commands/cicd/stage/update.js +2 -2
- package/dist/commands/cicd/template/defaults.js +2 -2
- package/dist/commands/cicd/template/delete.js +2 -2
- package/dist/commands/cicd/template/get.js +2 -2
- package/dist/commands/cicd/template/list.js +2 -2
- package/dist/commands/cicd/template/upsert.js +2 -2
- package/dist/commands/cicd/user/get.js +2 -2
- package/dist/commands/cicd/work/ahead-behind.js +2 -2
- package/dist/commands/cicd/work/create.js +2 -2
- package/dist/commands/cicd/work/delete.js +2 -2
- package/dist/commands/cicd/work/deployment-step/create.js +2 -2
- package/dist/commands/cicd/work/deployment-step/delete.js +2 -2
- package/dist/commands/cicd/work/deployment-step/list.js +2 -2
- package/dist/commands/cicd/work/deployment-step/reorder.js +2 -2
- package/dist/commands/cicd/work/deployment-step/salesforce-flows.js +2 -2
- package/dist/commands/cicd/work/deployment-step/types.js +2 -2
- package/dist/commands/cicd/work/deployment-step/update.js +2 -2
- package/dist/commands/cicd/work/done.js +2 -2
- package/dist/commands/cicd/work/environment-sync.js +2 -2
- package/dist/commands/cicd/work/get.js +2 -2
- package/dist/commands/cicd/work/list.js +2 -2
- package/dist/commands/cicd/work/open.js +2 -2
- package/dist/commands/cicd/work/promote.js +2 -2
- package/dist/commands/cicd/work/publish.js +2 -2
- package/dist/commands/cicd/work/push.js +2 -2
- package/dist/commands/cicd/work/set.js +2 -2
- package/dist/commands/cicd/work/status.js +2 -2
- package/dist/commands/cicd/work/submit.js +2 -2
- package/dist/commands/cicd/work/test/apex.js +2 -2
- package/dist/commands/cicd/work/test.js +2 -2
- package/dist/commands/cicd/work/update.js +2 -2
- package/dist/commands/help-agent.js +15 -0
- package/dist/commands/help.js +38 -0
- package/dist/commands/history/clear.js +42 -0
- package/dist/commands/history/list.js +50 -0
- package/dist/commands/support.js +15 -0
- package/dist/commands/testing/browser/execute.js +49 -0
- package/dist/commands/testing/browser/history.js +49 -0
- package/dist/commands/testing/browser/inspect.js +35 -0
- package/dist/commands/testing/browser/recorder.js +52 -0
- package/dist/commands/testing/browser/reports.js +33 -0
- package/dist/commands/testing/browser/screenshot.js +27 -0
- package/dist/commands/testing/browser/set-options.js +35 -0
- package/dist/commands/testing/browser/start.js +51 -0
- package/dist/commands/testing/browser/status.js +26 -0
- package/dist/commands/testing/browser/stop.js +34 -0
- package/dist/commands/testing/browser/view.js +35 -0
- package/dist/commands/testing/job/runs/abort.js +1 -1
- package/dist/commands/testing/job/runs/get.js +1 -1
- package/dist/commands/testing/job/runs/list.js +1 -1
- package/dist/commands/testing/job/runs/logs.js +1 -1
- package/dist/commands/testing/job/runs/search.js +1 -1
- package/dist/hooks/init/cicd-connection.js +59 -0
- package/dist/lib/agentia-command.js +69 -6
- package/dist/lib/cicd-command.js +3 -0
- package/dist/lib/cicd-connection.js +22 -0
- package/dist/lib/cicd-gateway.js +2 -1
- package/dist/lib/command-history-sanitization.js +9 -0
- package/dist/lib/command-history.js +11 -0
- package/dist/lib/command-output-buffer.js +6 -1
- package/dist/lib/defaults-store.js +3 -1
- package/dist/lib/dependency-from-changes.js +3 -1
- package/dist/lib/dependency-source-context.js +3 -0
- package/dist/lib/help-agent-command.js +3 -0
- package/dist/lib/help-agent-interaction-history.js +10 -0
- package/dist/lib/help-agent-session.js +3 -0
- package/dist/lib/mcp/result.js +41 -3
- package/dist/lib/mcp/server.js +3 -2
- package/dist/lib/mcp/testing-browser-tools.js +194 -0
- package/dist/lib/mcp/testing-tools.js +4 -3
- package/dist/lib/mcp/tool-annotations.js +32 -12
- package/dist/lib/mcp/tools.js +88 -37
- package/dist/lib/promotion-queue.js +5 -0
- package/dist/lib/promotion-run.js +2 -1
- package/dist/lib/runtime.js +1 -1
- package/dist/lib/support-ai-context.js +11 -0
- package/dist/lib/support-ai-stream-parser.js +4 -0
- package/dist/lib/support-ai.js +9 -0
- package/dist/lib/testing-browser-command.js +6 -0
- package/dist/lib/testing-browser-operations.js +17 -0
- package/dist/lib/testing-browser-requests.js +11 -0
- package/dist/lib/testing-browser-robot.js +9 -0
- package/dist/lib/testing-browser-session.js +14 -0
- package/dist/lib/testing-browser-state.js +17 -0
- package/dist/lib/testing-browser-stream.js +7 -0
- package/dist/lib/testing-browser-types.js +3 -0
- package/dist/lib/testing-browser-viewer-key.js +7 -0
- package/dist/lib/testing-gateway.js +2 -1
- package/dist/lib/testing-operations.js +21 -1
- package/dist/lib/testing-sanitization.js +2 -1
- package/dist/lib/work-promote.js +2 -1
- package/oclif.manifest.json +3108 -1450
- package/package.json +11 -4
- package/templates/skills/agentia-ai/SKILL.md +6 -2
- package/templates/skills/agentia-ai/references/ai-agents.md +19 -1
- package/templates/skills/agentia-cicd/SKILL.md +2 -2
- package/templates/skills/agentia-cicd/references/environments-and-credentials.md +16 -0
- package/templates/skills/agentia-cicd/references/promotions.md +10 -1
- package/templates/skills/agentia-metadata/SKILL.md +9 -3
- package/templates/skills/agentia-metadata/references/metadata-dependency.md +70 -0
- package/templates/skills/agentia-metadata/references/metadata-explore.md +8 -4
- package/templates/skills/agentia-testing/SKILL.md +9 -4
- package/templates/skills/agentia-testing/references/browser-testing.md +93 -0
- package/templates/skills/agentia-testing/references/flow-automation.md +112 -0
- package/templates/skills/agentia-testing/references/qforce.md +88 -0
- package/templates/skills/agentia-testing/references/qweb.md +103 -0
- package/templates/skills/agentia-testing/references/tests.md +17 -9
- package/dist/commands/testing/live/continue.js +0 -16
- package/dist/commands/testing/live/execute.js +0 -43
- package/dist/commands/testing/live/history.js +0 -40
- package/dist/commands/testing/live/inspect.js +0 -31
- package/dist/commands/testing/live/interrupt.js +0 -16
- package/dist/commands/testing/live/recorder.js +0 -42
- package/dist/commands/testing/live/reports.js +0 -31
- package/dist/commands/testing/live/screenshot.js +0 -25
- package/dist/commands/testing/live/set-options.js +0 -35
- package/dist/commands/testing/live/start.js +0 -58
- package/dist/commands/testing/live/status.js +0 -24
- package/dist/commands/testing/live/stop.js +0 -36
- package/dist/commands/testing/live/view.js +0 -36
- package/dist/lib/mcp/testing-live-tools.js +0 -226
- package/dist/lib/testing-live-command.js +0 -8
- package/dist/lib/testing-live-operations.js +0 -25
- package/dist/lib/testing-live-recorder.js +0 -11
- package/dist/lib/testing-live-robot.js +0 -9
- package/dist/lib/testing-live-state.js +0 -12
- package/dist/lib/testing-live-types.js +0 -3
|
@@ -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
|
-
|
|
|
49
|
+
| Browser testing | `testing browser start|stop|status|execute|inspect|screenshot|reports|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
|
-
##
|
|
68
|
+
## Browser Testing
|
|
69
69
|
|
|
70
70
|
Use a regression-owned job:
|
|
71
71
|
|
|
72
72
|
```sh
|
|
73
|
-
agentia testing
|
|
74
|
-
agentia testing
|
|
75
|
-
agentia testing
|
|
76
|
-
agentia testing
|
|
77
|
-
agentia testing
|
|
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
|
-
|
|
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,
|
|
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
|
|
|
@@ -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
|
|
@@ -1,42 +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 { recordTestingLiveSession } from '../../../lib/testing-live-operations.js';
|
|
5
|
-
export default class TestingLiveRecorder extends AgentiaCommand {
|
|
6
|
-
static args = testingLiveOptionalJobArg;
|
|
7
|
-
static description = 'Record CRT live interactions as bounded Robot Framework lines';
|
|
8
|
-
static enableJsonFlag = false;
|
|
9
|
-
static examples = ['<%= config.bin %> <%= command.id %> --project <project-id> --output recorded.robot'];
|
|
10
|
-
static flags = {
|
|
11
|
-
...testingLiveCommonFlags,
|
|
12
|
-
debug: Flags.boolean({ default: false, description: 'Print frame sizes and event types without frame bodies.' }),
|
|
13
|
-
'no-enable': Flags.boolean({ default: false, description: 'Do not manage the server recorder toggle.' }),
|
|
14
|
-
output: Flags.string({ char: 'o', description: 'Explicit .robot file to append recorded keywords to.' }),
|
|
15
|
-
};
|
|
16
|
-
async run() {
|
|
17
|
-
const { args, flags } = await this.parse(TestingLiveRecorder);
|
|
18
|
-
const controller = new AbortController();
|
|
19
|
-
const stop = () => controller.abort();
|
|
20
|
-
process.once('SIGINT', stop);
|
|
21
|
-
try {
|
|
22
|
-
return await recordTestingLiveSession({
|
|
23
|
-
appendRobot: flags.output,
|
|
24
|
-
jobId: args['job-id'],
|
|
25
|
-
noEnable: flags['no-enable'],
|
|
26
|
-
onDebugFrame: flags.debug
|
|
27
|
-
? ({ bytes, type }) => this.warn(`Recorder event ${type} (${bytes} bytes).`)
|
|
28
|
-
: undefined,
|
|
29
|
-
onError: (error) => this.warn(error.message),
|
|
30
|
-
onKeywordLine: (line) => this.log(line),
|
|
31
|
-
onReady: () => this.log('Recording CRT interactions. Press Ctrl-C to stop.'),
|
|
32
|
-
projectId: flags.project,
|
|
33
|
-
sessionId: flags['session-id'],
|
|
34
|
-
signal: controller.signal,
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
finally {
|
|
38
|
-
process.removeListener('SIGINT', stop);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
//# sourceMappingURL=recorder.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 { getTestingLiveReports } from '../../../lib/testing-live-operations.js';
|
|
5
|
-
export default class TestingLiveReports extends AgentiaCommand {
|
|
6
|
-
static args = testingLiveOptionalJobArg;
|
|
7
|
-
static description = 'List or save bounded report artifacts from an active CRT live session';
|
|
8
|
-
static examples = [
|
|
9
|
-
'<%= config.bin %> <%= command.id %> --project <project-id>',
|
|
10
|
-
'<%= config.bin %> <%= command.id %> --project <project-id> --output-dir ./reports',
|
|
11
|
-
];
|
|
12
|
-
static flags = {
|
|
13
|
-
...testingLiveCommonFlags,
|
|
14
|
-
'output-dir': Flags.string({ description: 'Explicit directory for log.html, report.html, and output.xml.' }),
|
|
15
|
-
};
|
|
16
|
-
async run() {
|
|
17
|
-
const { args, flags } = await this.parse(TestingLiveReports);
|
|
18
|
-
const result = await this.withSpinner('Reading CRT live reports', () => getTestingLiveReports({
|
|
19
|
-
jobId: args['job-id'],
|
|
20
|
-
outputDir: flags['output-dir'],
|
|
21
|
-
projectId: flags.project,
|
|
22
|
-
sessionId: flags['session-id'],
|
|
23
|
-
}));
|
|
24
|
-
this.display(() => {
|
|
25
|
-
for (const file of result.files)
|
|
26
|
-
this.log(`${file.name}: ${file.bytes} bytes${file.path === undefined ? '' : ` -> ${file.path}`}`);
|
|
27
|
-
});
|
|
28
|
-
return result;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
//# sourceMappingURL=reports.js.map
|
|
@@ -1,25 +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 { saveTestingLiveScreenshot } from '../../../lib/testing-live-operations.js';
|
|
5
|
-
export default class TestingLiveScreenshot extends AgentiaCommand {
|
|
6
|
-
static args = testingLiveOptionalJobArg;
|
|
7
|
-
static description = 'Save a bounded CRT live browser screenshot to an explicit file';
|
|
8
|
-
static examples = ['<%= config.bin %> <%= command.id %> --project <project-id> --output screenshot.png'];
|
|
9
|
-
static flags = {
|
|
10
|
-
...testingLiveCommonFlags,
|
|
11
|
-
output: Flags.string({ char: 'o', description: 'Explicit screenshot output path.', required: true }),
|
|
12
|
-
};
|
|
13
|
-
async run() {
|
|
14
|
-
const { args, flags } = await this.parse(TestingLiveScreenshot);
|
|
15
|
-
const result = await this.withSpinner('Saving CRT live screenshot', () => saveTestingLiveScreenshot({
|
|
16
|
-
jobId: args['job-id'],
|
|
17
|
-
output: flags.output,
|
|
18
|
-
projectId: flags.project,
|
|
19
|
-
sessionId: flags['session-id'],
|
|
20
|
-
}));
|
|
21
|
-
this.display(() => this.log(`Wrote ${result.bytes} bytes to ${result.path}.`));
|
|
22
|
-
return result;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
//# sourceMappingURL=screenshot.js.map
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { AgentiaCommand } from '../../../lib/agentia-command.js';
|
|
2
|
-
import { testingLiveCommonFlags, testingLiveOptionalJobArg, testingLiveRecorderOptionFlags, testingLiveRecorderOptions, } from '../../../lib/testing-live-command.js';
|
|
3
|
-
import { setTestingLiveOptions } from '../../../lib/testing-live-operations.js';
|
|
4
|
-
export default class TestingLiveSetOptions extends AgentiaCommand {
|
|
5
|
-
static args = testingLiveOptionalJobArg;
|
|
6
|
-
static description = 'Set the complete validated CRT live recorder option block';
|
|
7
|
-
static examples = [
|
|
8
|
-
'<%= config.bin %> <%= command.id %> --project <project-id> --enable --scroll-text --table-keywords',
|
|
9
|
-
];
|
|
10
|
-
static flags = { ...testingLiveCommonFlags, ...testingLiveRecorderOptionFlags };
|
|
11
|
-
async run() {
|
|
12
|
-
const { args, flags } = await this.parse(TestingLiveSetOptions);
|
|
13
|
-
const optionNames = [
|
|
14
|
-
'enable',
|
|
15
|
-
'healing-context',
|
|
16
|
-
'hover-text',
|
|
17
|
-
'scroll-text',
|
|
18
|
-
'system-state',
|
|
19
|
-
'table-keywords',
|
|
20
|
-
'verify-text',
|
|
21
|
-
];
|
|
22
|
-
if (!optionNames.some((name) => flags[name] !== undefined)) {
|
|
23
|
-
throw new Error('Provide at least one recorder option; unspecified options are set to false.');
|
|
24
|
-
}
|
|
25
|
-
const result = await setTestingLiveOptions({
|
|
26
|
-
jobId: args['job-id'],
|
|
27
|
-
projectId: flags.project,
|
|
28
|
-
recorder: testingLiveRecorderOptions(flags),
|
|
29
|
-
sessionId: flags['session-id'],
|
|
30
|
-
});
|
|
31
|
-
this.display(() => this.log('CRT live recorder options updated.'));
|
|
32
|
-
return result;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
//# sourceMappingURL=set-options.js.map
|
|
@@ -1,58 +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 { startTestingLive } from '../../../lib/testing-live-operations.js';
|
|
5
|
-
import { TESTING_LIVE_LIBRARIES } from '../../../lib/testing-live-types.js';
|
|
6
|
-
export default class TestingLiveStart extends AgentiaCommand {
|
|
7
|
-
static args = {
|
|
8
|
-
'job-id': Args.integer({ description: 'CRT job ID.', required: true }),
|
|
9
|
-
};
|
|
10
|
-
static description = 'Start and bootstrap a bounded Copado Robotic Testing live session';
|
|
11
|
-
static examples = [
|
|
12
|
-
'<%= config.bin %> <%= command.id %> <job-id> --project <project-id>',
|
|
13
|
-
'<%= config.bin %> <%= command.id %> <job-id> --project <project-id> --file smoke.robot --section "Login"',
|
|
14
|
-
];
|
|
15
|
-
static flags = {
|
|
16
|
-
...testingLiveCommonFlags,
|
|
17
|
-
description: Flags.string({ description: 'Nonsecret session label.' }),
|
|
18
|
-
file: Flags.string({ description: 'Robot Framework file used to bootstrap a selected test/task.' }),
|
|
19
|
-
'jap-ime': Flags.boolean({ default: false, description: 'Enable Japanese IME in the live environment.' }),
|
|
20
|
-
library: Flags.option({
|
|
21
|
-
default: 'QWeb',
|
|
22
|
-
description: 'Robot Framework library to bootstrap.',
|
|
23
|
-
options: [...TESTING_LIVE_LIBRARIES],
|
|
24
|
-
})(),
|
|
25
|
-
'no-bootstrap': Flags.boolean({ default: false, description: 'Create the host without readiness/bootstrap calls.' }),
|
|
26
|
-
'no-browser': Flags.boolean({ default: false, description: 'Do not open Chrome during QWeb/QForce bootstrap.' }),
|
|
27
|
-
'poll-interval': Flags.integer({ default: 3, description: 'Readiness polling interval in seconds.', min: 1 }),
|
|
28
|
-
screen: Flags.string({ description: 'Session screen as WIDTHxHEIGHTxDEPTH.' }),
|
|
29
|
-
section: Flags.string({ description: 'Robot test/task name to bootstrap.' }),
|
|
30
|
-
'section-index': Flags.integer({ description: 'One-based Robot test/task index to bootstrap.', min: 1 }),
|
|
31
|
-
'session-version': Flags.string({ description: 'CRT live environment version.' }),
|
|
32
|
-
timeout: Flags.integer({ default: 120, description: 'Readiness timeout in seconds.', min: 1 }),
|
|
33
|
-
viewport: Flags.string({ description: 'Session viewport as WIDTHxHEIGHT (24-bit depth).' }),
|
|
34
|
-
};
|
|
35
|
-
async run() {
|
|
36
|
-
const { args, flags } = await this.parse(TestingLiveStart);
|
|
37
|
-
const result = await this.withSpinner('Starting CRT live session', () => startTestingLive({
|
|
38
|
-
description: flags.description,
|
|
39
|
-
file: flags.file,
|
|
40
|
-
japIme: flags['jap-ime'],
|
|
41
|
-
jobId: args['job-id'],
|
|
42
|
-
library: flags.library,
|
|
43
|
-
noBootstrap: flags['no-bootstrap'],
|
|
44
|
-
noBrowser: flags['no-browser'],
|
|
45
|
-
pollIntervalMs: flags['poll-interval'] * 1000,
|
|
46
|
-
projectId: flags.project,
|
|
47
|
-
screen: flags.screen,
|
|
48
|
-
section: flags.section,
|
|
49
|
-
sectionIndex: flags['section-index'],
|
|
50
|
-
sessionVersion: flags['session-version'],
|
|
51
|
-
timeoutMs: flags.timeout * 1000,
|
|
52
|
-
viewport: flags.viewport,
|
|
53
|
-
}));
|
|
54
|
-
this.display(() => this.log(`CRT live session ${result.sessionId} is ready for job ${result.jobId}.`));
|
|
55
|
-
return result;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
//# sourceMappingURL=start.js.map
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { AgentiaCommand } from '../../../lib/agentia-command.js';
|
|
2
|
-
import { testingLiveCommonFlags, testingLiveOptionalJobArg } from '../../../lib/testing-live-command.js';
|
|
3
|
-
import { getTestingLiveStatus } from '../../../lib/testing-live-operations.js';
|
|
4
|
-
export default class TestingLiveStatus extends AgentiaCommand {
|
|
5
|
-
static args = testingLiveOptionalJobArg;
|
|
6
|
-
static description = 'Inspect sanitized status for the active CRT live session';
|
|
7
|
-
static examples = ['<%= config.bin %> <%= command.id %> --project <project-id> --json'];
|
|
8
|
-
static flags = testingLiveCommonFlags;
|
|
9
|
-
async run() {
|
|
10
|
-
const { args, flags } = await this.parse(TestingLiveStatus);
|
|
11
|
-
const result = await this.withSpinner('Reading CRT live status', () => getTestingLiveStatus({
|
|
12
|
-
jobId: args['job-id'],
|
|
13
|
-
projectId: flags.project,
|
|
14
|
-
sessionId: flags['session-id'],
|
|
15
|
-
}));
|
|
16
|
-
this.display(() => {
|
|
17
|
-
this.log(`Session: ${result.metadata.sessionId} (${result.metadata.status})`);
|
|
18
|
-
this.log(`Browser started: ${result.status.env.isBrowserStarted}`);
|
|
19
|
-
this.log(`Executor running: ${result.status.session.isRobotExecutorRunning}`);
|
|
20
|
-
});
|
|
21
|
-
return result;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
//# sourceMappingURL=status.js.map
|