@provartesting/provardx-cli 1.5.0-beta.6 → 1.5.0-beta.8
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/README.md +1 -1
- package/lib/commands/provar/auth/status.js +19 -1
- package/lib/commands/provar/auth/status.js.map +1 -1
- package/lib/mcp/docs/PROVAR_TEST_STEP_REFERENCE.md +1337 -0
- package/lib/mcp/licensing/licenseValidator.d.ts +3 -3
- package/lib/mcp/licensing/licenseValidator.js +4 -4
- package/lib/mcp/prompts/index.d.ts +2 -0
- package/lib/mcp/prompts/index.js +18 -0
- package/lib/mcp/prompts/index.js.map +1 -0
- package/lib/mcp/prompts/loopPrompts.d.ts +5 -0
- package/lib/mcp/prompts/loopPrompts.js +343 -0
- package/lib/mcp/prompts/loopPrompts.js.map +1 -0
- package/lib/mcp/prompts/migrationPrompts.d.ts +4 -0
- package/lib/mcp/prompts/migrationPrompts.js +207 -0
- package/lib/mcp/prompts/migrationPrompts.js.map +1 -0
- package/lib/mcp/server.js +38 -0
- package/lib/mcp/server.js.map +1 -1
- package/lib/mcp/tools/qualityHubApiTools.d.ts +3 -0
- package/lib/mcp/tools/qualityHubApiTools.js +134 -0
- package/lib/mcp/tools/qualityHubApiTools.js.map +1 -0
- package/lib/services/auth/credentials.d.ts +3 -0
- package/lib/services/auth/credentials.js +1 -0
- package/lib/services/auth/credentials.js.map +1 -1
- package/lib/services/auth/loginFlow.js +5 -5
- package/lib/services/auth/loginFlow.js.map +1 -1
- package/lib/services/qualityHub/client.d.ts +30 -0
- package/lib/services/qualityHub/client.js +30 -0
- package/lib/services/qualityHub/client.js.map +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,1337 @@
|
|
|
1
|
+
# Provar Test Step Reference
|
|
2
|
+
|
|
3
|
+
> **Source of truth** for AI-assisted test generation in the provardx-cli / Quality Hub MCP toolchain.
|
|
4
|
+
> All examples are sourced from the SalesCloud corpus. The `provar.qualityhub.examples.retrieve` tool returns real
|
|
5
|
+
> examples for additional grounding; `provar.testcase.validate` enforces all rules documented here.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## API ID Reference
|
|
10
|
+
|
|
11
|
+
| Step Type | API ID |
|
|
12
|
+
| --------------------- | ------------------------------------------------------------------------ |
|
|
13
|
+
| **Connection** | |
|
|
14
|
+
| ApexConnect | `com.provar.plugins.forcedotcom.core.testapis.ApexConnect` |
|
|
15
|
+
| UiConnect | `com.provar.plugins.forcedotcom.core.ui.UiConnect` |
|
|
16
|
+
| **Apex CRUD** | |
|
|
17
|
+
| ApexCreateObject | `com.provar.plugins.forcedotcom.core.testapis.ApexCreateObject` |
|
|
18
|
+
| ApexReadObject | `com.provar.plugins.forcedotcom.core.testapis.ApexReadObject` |
|
|
19
|
+
| ApexUpdateObject | `com.provar.plugins.forcedotcom.core.testapis.ApexUpdateObject` |
|
|
20
|
+
| ApexDeleteObject | `com.provar.plugins.forcedotcom.core.testapis.ApexDeleteObject` |
|
|
21
|
+
| ApexSoqlQuery | `com.provar.plugins.forcedotcom.core.testapis.ApexSoqlQuery` |
|
|
22
|
+
| **Apex Advanced** | |
|
|
23
|
+
| ApexBulk | `com.provar.plugins.forcedotcom.core.testapis.ApexBulk` |
|
|
24
|
+
| ApexExecute | `com.provar.plugins.forcedotcom.core.testapis.ApexExecute` |
|
|
25
|
+
| ApexConvertLead | `com.provar.plugins.forcedotcom.core.testapis.ApexConvertLead` |
|
|
26
|
+
| ApexExtractLayout | `com.provar.plugins.forcedotcom.core.testapis.ApexExtractLayout` |
|
|
27
|
+
| ApexAssertLayout | `com.provar.plugins.forcedotcom.core.testapis.ApexAssertLayout` |
|
|
28
|
+
| ApexApproveWorkItem | `com.provar.plugins.forcedotcom.core.testapis.ApexApproveWorkItem` |
|
|
29
|
+
| ApexSubmitForApproval | `com.provar.plugins.forcedotcom.core.testapis.ApexSubmitForApproval` |
|
|
30
|
+
| ApexLogForCleanup | `com.provar.plugins.forcedotcom.core.testapis.ApexLogForCleanup` |
|
|
31
|
+
| **UI Steps** | |
|
|
32
|
+
| UiWithScreen | `com.provar.plugins.forcedotcom.core.ui.UiWithScreen` |
|
|
33
|
+
| UiDoAction | `com.provar.plugins.forcedotcom.core.ui.UiDoAction` |
|
|
34
|
+
| UiAssert | `com.provar.plugins.forcedotcom.core.ui.UiAssert` |
|
|
35
|
+
| UiWithRow | `com.provar.plugins.forcedotcom.core.ui.UiWithRow` |
|
|
36
|
+
| UiHandleAlert | `com.provar.plugins.forcedotcom.core.ui.UiHandleAlert` |
|
|
37
|
+
| UiNavigate | `com.provar.plugins.forcedotcom.core.ui.UiNavigate` |
|
|
38
|
+
| **Control Flow** | |
|
|
39
|
+
| SetValues | `com.provar.plugins.bundled.apis.control.SetValues` |
|
|
40
|
+
| StepGroup | `com.provar.plugins.bundled.apis.control.StepGroup` |
|
|
41
|
+
| If | `com.provar.plugins.bundled.apis.If` |
|
|
42
|
+
| ForEach | `com.provar.plugins.bundled.apis.control.ForEach` |
|
|
43
|
+
| DoWhile | `com.provar.plugins.bundled.apis.control.DoWhile` |
|
|
44
|
+
| WaitFor | `com.provar.plugins.bundled.apis.control.WaitFor` |
|
|
45
|
+
| TryCatchFinally | `com.provar.plugins.bundled.apis.control.TryCatchFinally` |
|
|
46
|
+
| Switch | `com.provar.plugins.bundled.apis.Switch` |
|
|
47
|
+
| Sleep | `com.provar.plugins.bundled.apis.control.Sleep` |
|
|
48
|
+
| Fail | `com.provar.plugins.bundled.apis.control.Fail` |
|
|
49
|
+
| CallTest | `com.provar.plugins.bundled.apis.control.CallTest` |
|
|
50
|
+
| **Assertions** | |
|
|
51
|
+
| AssertValues | `com.provar.plugins.bundled.apis.AssertValues` |
|
|
52
|
+
| **BDD** | |
|
|
53
|
+
| Given | `com.provar.plugins.bundled.apis.bdd.Given` |
|
|
54
|
+
| When | `com.provar.plugins.bundled.apis.bdd.When` |
|
|
55
|
+
| Then | `com.provar.plugins.bundled.apis.bdd.Then` |
|
|
56
|
+
| And | `com.provar.plugins.bundled.apis.bdd.And` |
|
|
57
|
+
| But | `com.provar.plugins.bundled.apis.bdd.But` |
|
|
58
|
+
| **Design** | |
|
|
59
|
+
| ActualResult | `com.provar.plugins.bundled.apis.control.ActualResult` |
|
|
60
|
+
| DesignStep | `com.provar.plugins.bundled.apis.control.DesignStep` |
|
|
61
|
+
| **Database** | |
|
|
62
|
+
| DbConnect | `com.provar.plugins.bundled.apis.db.DbConnect` |
|
|
63
|
+
| DbRead | `com.provar.plugins.bundled.apis.db.DbRead` |
|
|
64
|
+
| DbInsert | `com.provar.plugins.bundled.apis.db.DbInsert` |
|
|
65
|
+
| DbUpdate | `com.provar.plugins.bundled.apis.db.DbUpdate` |
|
|
66
|
+
| DbDelete | `com.provar.plugins.bundled.apis.db.DbDelete` |
|
|
67
|
+
| SqlQuery | `com.provar.plugins.bundled.apis.db.SqlQuery` |
|
|
68
|
+
| **Web Service** | |
|
|
69
|
+
| WebConnect | `com.provar.plugins.bundled.apis.restservice.WebConnect` |
|
|
70
|
+
| RestRequest | `com.provar.plugins.bundled.apis.restservice.RestRequest` |
|
|
71
|
+
| SoapRequest | `com.provar.plugins.bundled.apis.restservice.SoapRequest` |
|
|
72
|
+
| **Messaging** | |
|
|
73
|
+
| PublishMessage | `com.provar.plugins.bundled.apis.messaging.PublishMessage` |
|
|
74
|
+
| Subscribe | `com.provar.plugins.bundled.apis.messaging.Subscribe` |
|
|
75
|
+
| ReceiveMessage | `com.provar.plugins.bundled.apis.messaging.ReceiveMessage` |
|
|
76
|
+
| SendMessage | `com.provar.plugins.bundled.apis.messaging.SendMessage` |
|
|
77
|
+
| **Utility** | |
|
|
78
|
+
| ListCompare | `com.provar.plugins.bundled.apis.list.ListCompare` |
|
|
79
|
+
| Match | `com.provar.plugins.bundled.apis.string.Match` |
|
|
80
|
+
| Read | `com.provar.plugins.bundled.apis.io.Read` |
|
|
81
|
+
| Write | `com.provar.plugins.bundled.apis.io.Write` |
|
|
82
|
+
| Split | `com.provar.plugins.bundled.apis.string.Split` |
|
|
83
|
+
| Replace | `com.provar.plugins.bundled.apis.string.Replace` |
|
|
84
|
+
| **ProvarAI / Labs** | |
|
|
85
|
+
| GenerateTestData | `com.provar.plugins.forcedotcom.core.testapis.generate.GenerateTestData` |
|
|
86
|
+
| GenerateTestCase | `com.provar.plugins.forcedotcom.core.testapis.GenerateTestCase` |
|
|
87
|
+
| PageObjectCleaner | `com.provar.plugins.bundled.apis.provarlabs.PageObjectCleaner` |
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Common AI Hallucinations — Do Not Use
|
|
92
|
+
|
|
93
|
+
The following argument IDs look plausible but are invalid and will fail validation:
|
|
94
|
+
|
|
95
|
+
| Invalid argument | Correct alternative |
|
|
96
|
+
| ----------------------------- | ---------------------------------------------------------- |
|
|
97
|
+
| `autoPopulateRequiredFields` | Not supported — populate fields explicitly |
|
|
98
|
+
| `assertObjectFieldsPopulated` | Use `UiAssert` or `ApexReadObject` instead |
|
|
99
|
+
| `commandTimeout` | Not a valid argument on any step |
|
|
100
|
+
| `waitForPageLoad` | Use `beforeWait`/`afterWait` with `uiWait` URI |
|
|
101
|
+
| `screenshotOnFailure` | Use `captureBefore`/`captureAfter` (string "true"/"false") |
|
|
102
|
+
| `closeAllOtherTabs` | The correct id is `closeAllPrimaryTabs` (ApexConnect only) |
|
|
103
|
+
| `connectionType` | Not a step argument; connection type is implied by apiId |
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Connection Steps
|
|
108
|
+
|
|
109
|
+
### ApexConnect
|
|
110
|
+
|
|
111
|
+
Establishes a Salesforce connection (API + optional UI). Usually the first step in every test. Use `autoCleanup="true"` to automatically log out after the test; omit it only when you want the connection to persist into a parent scope.
|
|
112
|
+
|
|
113
|
+
> **`connectionId` must use `valueClass="id"`** (a GUID string), not `valueClass="string"`. The validator
|
|
114
|
+
> enforces this (rule APEX-CONNECT-CONNID-001).
|
|
115
|
+
|
|
116
|
+
> **ApexConnect vs UiConnect:** ApexConnect opens both an API connection and (optionally) a UI browser session.
|
|
117
|
+
> UiConnect opens only a browser session, using an existing ApexConnect result as its Salesforce credential.
|
|
118
|
+
> In most test cases you need only ApexConnect.
|
|
119
|
+
|
|
120
|
+
```xml
|
|
121
|
+
<apiCall apiId="com.provar.plugins.forcedotcom.core.testapis.ApexConnect"
|
|
122
|
+
name="ApexConnect" testItemId="1"
|
|
123
|
+
title="Salesforce Connect: SalesUser (Test)">
|
|
124
|
+
<arguments>
|
|
125
|
+
<argument id="connectionName">
|
|
126
|
+
<value class="value" valueClass="string">SalesUser</value>
|
|
127
|
+
</argument>
|
|
128
|
+
<argument id="connectionId">
|
|
129
|
+
<value class="value" valueClass="id">74c34c63-ad34-43d9-bb12-cd783bd9bcdd</value>
|
|
130
|
+
</argument>
|
|
131
|
+
<argument id="resultName">
|
|
132
|
+
<value class="value" valueClass="string">DemoOrg</value>
|
|
133
|
+
</argument>
|
|
134
|
+
<argument id="resultScope">
|
|
135
|
+
<value class="value" valueClass="string">Test</value>
|
|
136
|
+
</argument>
|
|
137
|
+
<argument id="uiApplicationName">
|
|
138
|
+
<value class="value" valueClass="string">LightningSales</value>
|
|
139
|
+
</argument>
|
|
140
|
+
<argument id="quickUiLogin">
|
|
141
|
+
<value class="value" valueClass="boolean">true</value>
|
|
142
|
+
</argument>
|
|
143
|
+
<argument id="closeAllPrimaryTabs">
|
|
144
|
+
<value class="value" valueClass="boolean">true</value>
|
|
145
|
+
</argument>
|
|
146
|
+
<argument id="reuseConnectionName"/>
|
|
147
|
+
<argument id="alreadyOpenBehaviour">
|
|
148
|
+
<value class="value" valueClass="string">Fail</value>
|
|
149
|
+
</argument>
|
|
150
|
+
<argument id="privateBrowsingMode"/>
|
|
151
|
+
<argument id="enableObjectIdLogging">
|
|
152
|
+
<value class="value" valueClass="boolean">true</value>
|
|
153
|
+
</argument>
|
|
154
|
+
<argument id="autoCleanup">
|
|
155
|
+
<value class="value" valueClass="boolean">true</value>
|
|
156
|
+
</argument>
|
|
157
|
+
<argument id="cleanupConnectionName"/>
|
|
158
|
+
<argument id="lightningMode">
|
|
159
|
+
<value class="value" valueClass="string">enable</value>
|
|
160
|
+
</argument>
|
|
161
|
+
<argument id="webBrowser"/>
|
|
162
|
+
</arguments>
|
|
163
|
+
</apiCall>
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Valid `alreadyOpenBehaviour` values:** `Reuse` | `Fail`
|
|
167
|
+
**Valid `lightningMode` values:** `enable` | `default`
|
|
168
|
+
**Valid `resultScope` values:** `Test` | `Global` | `Folder`
|
|
169
|
+
|
|
170
|
+
### UiConnect
|
|
171
|
+
|
|
172
|
+
Opens a browser-only UI session. Use this when you have a separate ApexConnect for API operations and need an independent browser window. Fewer arguments than ApexConnect — it does not manage Salesforce API credentials.
|
|
173
|
+
|
|
174
|
+
> **UiConnect does NOT accept:** `autoCleanup`, `enableObjectIdLogging`, `quickUiLogin`, `closeAllPrimaryTabs`,
|
|
175
|
+
> `alreadyOpenBehaviour`, `lightningMode`, `uiApplicationName`, `cleanupConnectionName`.
|
|
176
|
+
> Using these on UiConnect will fail validation (rule UI-CONNECT-ARGS-001).
|
|
177
|
+
|
|
178
|
+
```xml
|
|
179
|
+
<apiCall apiId="com.provar.plugins.forcedotcom.core.ui.UiConnect"
|
|
180
|
+
name="UiConnect" testItemId="1"
|
|
181
|
+
title="UI Connect: DemoOrg">
|
|
182
|
+
<arguments>
|
|
183
|
+
<argument id="connectionName">
|
|
184
|
+
<value class="value" valueClass="string">DemoOrg</value>
|
|
185
|
+
</argument>
|
|
186
|
+
<argument id="resultName">
|
|
187
|
+
<value class="value" valueClass="string">DemoOrg</value>
|
|
188
|
+
</argument>
|
|
189
|
+
<argument id="resultScope">
|
|
190
|
+
<value class="value" valueClass="string">Test</value>
|
|
191
|
+
</argument>
|
|
192
|
+
<argument id="reuseConnectionName"/>
|
|
193
|
+
<argument id="privateBrowsingMode"/>
|
|
194
|
+
<argument id="webBrowser"/>
|
|
195
|
+
</arguments>
|
|
196
|
+
</apiCall>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## UI Steps
|
|
202
|
+
|
|
203
|
+
UI steps must always be nested inside a `UiWithScreen` block. Never place `UiDoAction` or `UiAssert` directly in the top-level `<steps>` list.
|
|
204
|
+
|
|
205
|
+
### UiWithScreen
|
|
206
|
+
|
|
207
|
+
Navigates to (or asserts presence of) a Salesforce screen, then runs substeps against it. All UI actions and assertions go inside the `<clause name="substeps">` block.
|
|
208
|
+
|
|
209
|
+
**Navigation rules:**
|
|
210
|
+
|
|
211
|
+
- The first `UiWithScreen` in a test **must** use `navigate="Always"` or `navigate="IfNecessary"`. Never `"Dont"` for the first screen.
|
|
212
|
+
- Subsequent screens in the same flow should use `navigate="Dont"` when Salesforce has already navigated there (e.g., after clicking Save the record view is already open).
|
|
213
|
+
- `navigate="Always"` on an `Edit` or `View` action **requires** `sfUiTargetObjectId` (the record ID). Without it, Provar cannot navigate to the correct record.
|
|
214
|
+
- `sfUiTargetResultName` captures the record ID that Salesforce creates (useful on `New` action screens after save).
|
|
215
|
+
|
|
216
|
+
**Target URI format:** `sf:ui:target?object=OBJECT&action=ACTION`
|
|
217
|
+
|
|
218
|
+
Valid `action` values: `ObjectHome` | `New` | `View` | `Edit` | `Delete` | `Clone`
|
|
219
|
+
|
|
220
|
+
```xml
|
|
221
|
+
<!-- First screen: navigate=Always required -->
|
|
222
|
+
<apiCall apiId="com.provar.plugins.forcedotcom.core.ui.UiWithScreen"
|
|
223
|
+
name="UiWithScreen" testItemId="2"
|
|
224
|
+
title="On SF Opportunity Home screen">
|
|
225
|
+
<arguments>
|
|
226
|
+
<argument id="uiConnectionName">
|
|
227
|
+
<value class="value" valueClass="string">DemoOrg</value>
|
|
228
|
+
</argument>
|
|
229
|
+
<argument id="target">
|
|
230
|
+
<value class="uiTarget" uri="sf:ui:target?object=Opportunity&action=ObjectHome"/>
|
|
231
|
+
</argument>
|
|
232
|
+
<argument id="navigate">
|
|
233
|
+
<value class="value" valueClass="string">Always</value>
|
|
234
|
+
</argument>
|
|
235
|
+
<argument id="targetDescription">
|
|
236
|
+
<value class="value" valueClass="string">On SF Opportunity Home screen</value>
|
|
237
|
+
</argument>
|
|
238
|
+
<argument id="windowSelection">
|
|
239
|
+
<value class="value" valueClass="string">Default</value>
|
|
240
|
+
</argument>
|
|
241
|
+
<argument id="windowSize">
|
|
242
|
+
<value class="value" valueClass="string">Default</value>
|
|
243
|
+
</argument>
|
|
244
|
+
<argument id="closeWindow"/>
|
|
245
|
+
<argument id="captureBefore">
|
|
246
|
+
<value class="value" valueClass="string">false</value>
|
|
247
|
+
</argument>
|
|
248
|
+
<argument id="captureAfter">
|
|
249
|
+
<value class="value" valueClass="string">false</value>
|
|
250
|
+
</argument>
|
|
251
|
+
</arguments>
|
|
252
|
+
<clauses>
|
|
253
|
+
<clause name="substeps" testItemId="3">
|
|
254
|
+
<steps>
|
|
255
|
+
<!-- UiDoAction and UiAssert steps go here -->
|
|
256
|
+
</steps>
|
|
257
|
+
</clause>
|
|
258
|
+
</clauses>
|
|
259
|
+
</apiCall>
|
|
260
|
+
|
|
261
|
+
<!-- New screen: navigate=Dont (already arrived via New button click), capture resulting record ID -->
|
|
262
|
+
<apiCall apiId="com.provar.plugins.forcedotcom.core.ui.UiWithScreen"
|
|
263
|
+
name="UiWithScreen" testItemId="5"
|
|
264
|
+
title="On SF Opportunity New screen">
|
|
265
|
+
<arguments>
|
|
266
|
+
<argument id="uiConnectionName">
|
|
267
|
+
<value class="value" valueClass="string">DemoOrg</value>
|
|
268
|
+
</argument>
|
|
269
|
+
<argument id="target">
|
|
270
|
+
<value class="uiTarget" uri="sf:ui:target?object=Opportunity&noOverride=true&action=New"/>
|
|
271
|
+
</argument>
|
|
272
|
+
<argument id="navigate">
|
|
273
|
+
<value class="value" valueClass="string">Dont</value>
|
|
274
|
+
</argument>
|
|
275
|
+
<argument id="targetDescription">
|
|
276
|
+
<value class="value" valueClass="string">On SF Opportunity New screen</value>
|
|
277
|
+
</argument>
|
|
278
|
+
<argument id="windowSelection">
|
|
279
|
+
<value class="value" valueClass="string">Default</value>
|
|
280
|
+
</argument>
|
|
281
|
+
<argument id="windowSize">
|
|
282
|
+
<value class="value" valueClass="string">Default</value>
|
|
283
|
+
</argument>
|
|
284
|
+
<argument id="closeWindow"/>
|
|
285
|
+
<argument id="captureBefore">
|
|
286
|
+
<value class="value" valueClass="string">false</value>
|
|
287
|
+
</argument>
|
|
288
|
+
<argument id="captureAfter">
|
|
289
|
+
<value class="value" valueClass="string">false</value>
|
|
290
|
+
</argument>
|
|
291
|
+
<argument id="sfUiTargetResultName">
|
|
292
|
+
<value class="value" valueClass="string">opportunityId</value>
|
|
293
|
+
</argument>
|
|
294
|
+
<argument id="sfUiTargetResultScope">
|
|
295
|
+
<value class="value" valueClass="string">Test</value>
|
|
296
|
+
</argument>
|
|
297
|
+
</arguments>
|
|
298
|
+
<clauses>
|
|
299
|
+
<clause name="substeps" testItemId="6">
|
|
300
|
+
<steps>
|
|
301
|
+
<!-- fill fields, then Save -->
|
|
302
|
+
</steps>
|
|
303
|
+
</clause>
|
|
304
|
+
</clauses>
|
|
305
|
+
</apiCall>
|
|
306
|
+
|
|
307
|
+
<!-- View screen: navigate=Always requires sfUiTargetObjectId -->
|
|
308
|
+
<apiCall apiId="com.provar.plugins.forcedotcom.core.ui.UiWithScreen"
|
|
309
|
+
name="UiWithScreen" testItemId="12"
|
|
310
|
+
title="On SF Opportunity View screen">
|
|
311
|
+
<arguments>
|
|
312
|
+
<argument id="uiConnectionName">
|
|
313
|
+
<value class="value" valueClass="string">DemoOrg</value>
|
|
314
|
+
</argument>
|
|
315
|
+
<argument id="target">
|
|
316
|
+
<value class="uiTarget" uri="sf:ui:target?object=Opportunity&noOverride=true&action=View"/>
|
|
317
|
+
</argument>
|
|
318
|
+
<argument id="navigate">
|
|
319
|
+
<value class="value" valueClass="string">Always</value>
|
|
320
|
+
</argument>
|
|
321
|
+
<argument id="targetDescription">
|
|
322
|
+
<value class="value" valueClass="string">On SF Opportunity View screen</value>
|
|
323
|
+
</argument>
|
|
324
|
+
<argument id="windowSelection">
|
|
325
|
+
<value class="value" valueClass="string">Default</value>
|
|
326
|
+
</argument>
|
|
327
|
+
<argument id="windowSize">
|
|
328
|
+
<value class="value" valueClass="string">Default</value>
|
|
329
|
+
</argument>
|
|
330
|
+
<argument id="closeWindow"/>
|
|
331
|
+
<argument id="captureBefore">
|
|
332
|
+
<value class="value" valueClass="string">false</value>
|
|
333
|
+
</argument>
|
|
334
|
+
<argument id="captureAfter">
|
|
335
|
+
<value class="value" valueClass="string">false</value>
|
|
336
|
+
</argument>
|
|
337
|
+
<argument id="sfUiTargetObjectId">
|
|
338
|
+
<value class="variable">
|
|
339
|
+
<path element="opportunityId"/>
|
|
340
|
+
</value>
|
|
341
|
+
</argument>
|
|
342
|
+
</arguments>
|
|
343
|
+
<clauses>
|
|
344
|
+
<clause name="substeps" testItemId="13">
|
|
345
|
+
<steps>
|
|
346
|
+
<!-- UiAssert steps go here -->
|
|
347
|
+
</steps>
|
|
348
|
+
</clause>
|
|
349
|
+
</clauses>
|
|
350
|
+
</apiCall>
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### UiDoAction
|
|
354
|
+
|
|
355
|
+
Performs a single UI interaction on a field or button. The `interaction` URI determines the action type.
|
|
356
|
+
|
|
357
|
+
**Interaction types:**
|
|
358
|
+
|
|
359
|
+
- `ui:interaction?name=action` — click a button or link
|
|
360
|
+
- `ui:interaction?name=set` — fill/type into a field or select a picklist value
|
|
361
|
+
- `ui:interaction?name=file` — upload a file (uses `fileLocation` instead of `value`)
|
|
362
|
+
|
|
363
|
+
**Locator URI format:** `ui:locator?name=FIELD_OR_BUTTON_NAME&binding=ENCODED_BINDING`
|
|
364
|
+
|
|
365
|
+
The binding component URL-encodes `sf:ui:binding:object?object=OBJECT&field=FIELD` for field locators, or `sf:ui:binding:object?object=OBJECT&action=ACTION` for action locators.
|
|
366
|
+
|
|
367
|
+
```xml
|
|
368
|
+
<!-- Click a button (interaction=action) -->
|
|
369
|
+
<apiCall apiId="com.provar.plugins.forcedotcom.core.ui.UiDoAction"
|
|
370
|
+
name="UiDoAction" testItemId="4"
|
|
371
|
+
title="Click the New button">
|
|
372
|
+
<arguments>
|
|
373
|
+
<argument id="locator">
|
|
374
|
+
<value class="uiLocator" uri="ui:locator?name=New&binding=sf%3Aui%3Abinding%3Aobject%3Fobject%3DOpportunity%26action%3DNew"/>
|
|
375
|
+
</argument>
|
|
376
|
+
<argument id="interaction">
|
|
377
|
+
<value class="uiInteraction" uri="ui:interaction?name=action"/>
|
|
378
|
+
</argument>
|
|
379
|
+
<argument id="hover">
|
|
380
|
+
<value class="value" valueClass="boolean">false</value>
|
|
381
|
+
</argument>
|
|
382
|
+
<argument id="captureBefore">
|
|
383
|
+
<value class="value" valueClass="string">false</value>
|
|
384
|
+
</argument>
|
|
385
|
+
<argument id="captureAfter">
|
|
386
|
+
<value class="value" valueClass="string">false</value>
|
|
387
|
+
</argument>
|
|
388
|
+
<argument id="beforeWait">
|
|
389
|
+
<value class="uiWait" uri="default"/>
|
|
390
|
+
</argument>
|
|
391
|
+
<argument id="afterWait">
|
|
392
|
+
<value class="uiWait" uri="default"/>
|
|
393
|
+
</argument>
|
|
394
|
+
<argument id="interactionDescription">
|
|
395
|
+
<value class="value" valueClass="string">Click the New button</value>
|
|
396
|
+
</argument>
|
|
397
|
+
<argument id="autoRetry"/>
|
|
398
|
+
</arguments>
|
|
399
|
+
</apiCall>
|
|
400
|
+
|
|
401
|
+
<!-- Set a text/picklist field (interaction=set) -->
|
|
402
|
+
<apiCall apiId="com.provar.plugins.forcedotcom.core.ui.UiDoAction"
|
|
403
|
+
name="UiDoAction" testItemId="7"
|
|
404
|
+
title="Set the Opportunity Name field to Test">
|
|
405
|
+
<arguments>
|
|
406
|
+
<argument id="locator">
|
|
407
|
+
<value class="uiLocator" uri="ui:locator?name=Name&binding=sf%3Aui%3Abinding%3Aobject%3Fobject%3DOpportunity%26field%3DName"/>
|
|
408
|
+
</argument>
|
|
409
|
+
<argument id="interaction">
|
|
410
|
+
<value class="uiInteraction" uri="ui:interaction?name=set"/>
|
|
411
|
+
</argument>
|
|
412
|
+
<argument id="value">
|
|
413
|
+
<value class="value" valueClass="string">Test</value>
|
|
414
|
+
</argument>
|
|
415
|
+
<argument id="blur">
|
|
416
|
+
<value class="value" valueClass="boolean">false</value>
|
|
417
|
+
</argument>
|
|
418
|
+
<argument id="pressEnter">
|
|
419
|
+
<value class="value" valueClass="boolean">false</value>
|
|
420
|
+
</argument>
|
|
421
|
+
<argument id="captureBefore">
|
|
422
|
+
<value class="value" valueClass="string">false</value>
|
|
423
|
+
</argument>
|
|
424
|
+
<argument id="captureAfter">
|
|
425
|
+
<value class="value" valueClass="string">false</value>
|
|
426
|
+
</argument>
|
|
427
|
+
<argument id="beforeWait">
|
|
428
|
+
<value class="uiWait" uri="default"/>
|
|
429
|
+
</argument>
|
|
430
|
+
<argument id="afterWait">
|
|
431
|
+
<value class="uiWait" uri="default"/>
|
|
432
|
+
</argument>
|
|
433
|
+
<argument id="interactionDescription">
|
|
434
|
+
<value class="value" valueClass="string">Set the Opportunity Name field to Test</value>
|
|
435
|
+
</argument>
|
|
436
|
+
<argument id="autoRetry"/>
|
|
437
|
+
</arguments>
|
|
438
|
+
</apiCall>
|
|
439
|
+
|
|
440
|
+
<!-- Upload a file (interaction=file) -->
|
|
441
|
+
<apiCall apiId="com.provar.plugins.forcedotcom.core.ui.UiDoAction"
|
|
442
|
+
name="UiDoAction" testItemId="15"
|
|
443
|
+
title="Upload attachment file">
|
|
444
|
+
<arguments>
|
|
445
|
+
<argument id="locator">
|
|
446
|
+
<value class="uiLocator" uri="ui:locator?name=AttachFile&binding=sf%3Aui%3Abinding%3Aobject%3Fobject%3DOpportunity%26action%3DAttachFile%26relationship%3DCombinedAttachments"/>
|
|
447
|
+
</argument>
|
|
448
|
+
<argument id="interaction">
|
|
449
|
+
<value class="uiInteraction" uri="ui:interaction?name=file"/>
|
|
450
|
+
</argument>
|
|
451
|
+
<argument id="fileLocation">
|
|
452
|
+
<value class="value" valueClass="string">templates/TestData.xlsx</value>
|
|
453
|
+
</argument>
|
|
454
|
+
<argument id="fileContents"/>
|
|
455
|
+
<argument id="captureBefore">
|
|
456
|
+
<value class="value" valueClass="string">false</value>
|
|
457
|
+
</argument>
|
|
458
|
+
<argument id="captureAfter">
|
|
459
|
+
<value class="value" valueClass="string">false</value>
|
|
460
|
+
</argument>
|
|
461
|
+
<argument id="beforeWait">
|
|
462
|
+
<value class="uiWait" uri="default"/>
|
|
463
|
+
</argument>
|
|
464
|
+
<argument id="afterWait">
|
|
465
|
+
<value class="uiWait" uri="default"/>
|
|
466
|
+
</argument>
|
|
467
|
+
<argument id="interactionDescription">
|
|
468
|
+
<value class="value" valueClass="string">Upload attachment file</value>
|
|
469
|
+
</argument>
|
|
470
|
+
<argument id="autoRetry">
|
|
471
|
+
<value class="uiWait" uri="ui:wait:autoRetry:timeout=10"/>
|
|
472
|
+
</argument>
|
|
473
|
+
</arguments>
|
|
474
|
+
</apiCall>
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
> **Rule UI-DOACTION-VALUE-001:** When `interaction` is `set`, the `value` argument is required.
|
|
478
|
+
> When `interaction` is `action`, the `value` argument must be absent.
|
|
479
|
+
|
|
480
|
+
### UiAssert
|
|
481
|
+
|
|
482
|
+
Verifies field values or element state on the current screen. Must always include `columnAssertions`, `pageAssertions`, `resultScope`, `captureAfter`, `beforeWait`, and `autoRetry` — even when empty.
|
|
483
|
+
|
|
484
|
+
> **Rule UI-ASSERT-STRUCT-001:** All six arguments above are required. Omitting any will fail validation.
|
|
485
|
+
>
|
|
486
|
+
> **Rule UI-ASSERT-STRUCT-002:** Do NOT include `generatedParameters` on `UiAssert`. Unlike `UiDoAction`,
|
|
487
|
+
> `UiAssert` does not use `generatedParameters` for its field assertions.
|
|
488
|
+
>
|
|
489
|
+
> **Rule UI-ASSERT-FIELDLOCATOR-002:** The `uiFieldAssertion` uses a bare `<fieldLocator uri="..."/>` element,
|
|
490
|
+
> NOT a `<value class="uiLocator">` wrapper.
|
|
491
|
+
|
|
492
|
+
```xml
|
|
493
|
+
<!-- Assert a field value -->
|
|
494
|
+
<apiCall apiId="com.provar.plugins.forcedotcom.core.ui.UiAssert"
|
|
495
|
+
name="UiAssert" testItemId="14"
|
|
496
|
+
title="UI Assert: Name">
|
|
497
|
+
<arguments>
|
|
498
|
+
<argument id="resultName">
|
|
499
|
+
<value class="value" valueClass="string">Values</value>
|
|
500
|
+
</argument>
|
|
501
|
+
<argument id="resultScope">
|
|
502
|
+
<value class="value" valueClass="string">Test</value>
|
|
503
|
+
</argument>
|
|
504
|
+
<argument id="fieldAssertions">
|
|
505
|
+
<value class="valueList" mutable="Mutable">
|
|
506
|
+
<uiFieldAssertion resultName="Name">
|
|
507
|
+
<fieldLocator uri="ui:locator?name=Name&binding=sf%3Aui%3Abinding%3Aobject%3Fobject%3DOpportunity%26field%3DName"/>
|
|
508
|
+
<attributeAssertions>
|
|
509
|
+
<uiAttributeAssertion attributeName="value" comparisonType="EqualTo" normalize="true">
|
|
510
|
+
<value class="value" valueClass="string">Test</value>
|
|
511
|
+
</uiAttributeAssertion>
|
|
512
|
+
</attributeAssertions>
|
|
513
|
+
</uiFieldAssertion>
|
|
514
|
+
</value>
|
|
515
|
+
</argument>
|
|
516
|
+
<argument id="captureAfter">
|
|
517
|
+
<value class="value" valueClass="string">false</value>
|
|
518
|
+
</argument>
|
|
519
|
+
<argument id="columnAssertions">
|
|
520
|
+
<value class="valueList" mutable="Mutable"/>
|
|
521
|
+
</argument>
|
|
522
|
+
<argument id="pageAssertions">
|
|
523
|
+
<value class="valueList" mutable="Mutable"/>
|
|
524
|
+
</argument>
|
|
525
|
+
<argument id="beforeWait"/>
|
|
526
|
+
<argument id="autoRetry"/>
|
|
527
|
+
</arguments>
|
|
528
|
+
</apiCall>
|
|
529
|
+
|
|
530
|
+
<!-- Assert a related list row count -->
|
|
531
|
+
<apiCall apiId="com.provar.plugins.forcedotcom.core.ui.UiAssert"
|
|
532
|
+
name="UiAssert" testItemId="16"
|
|
533
|
+
title="UI Assert: Attachment count">
|
|
534
|
+
<arguments>
|
|
535
|
+
<argument id="resultName">
|
|
536
|
+
<value class="value" valueClass="string">Values</value>
|
|
537
|
+
</argument>
|
|
538
|
+
<argument id="resultScope">
|
|
539
|
+
<value class="value" valueClass="string">Test</value>
|
|
540
|
+
</argument>
|
|
541
|
+
<argument id="fieldAssertions">
|
|
542
|
+
<value class="valueList" mutable="Mutable">
|
|
543
|
+
<uiFieldAssertion resultName="CombinedAttachments">
|
|
544
|
+
<fieldLocator uri="ui:locator?name=CombinedAttachments&binding=sf%3Aui%3Abinding%3Aobject%3Fobject%3DOpportunity%26relationship%3DCombinedAttachments"/>
|
|
545
|
+
<attributeAssertions>
|
|
546
|
+
<uiAttributeAssertion attributeName="totalRowCount" comparisonType="EqualTo">
|
|
547
|
+
<value class="value" valueClass="string">1</value>
|
|
548
|
+
</uiAttributeAssertion>
|
|
549
|
+
<uiAttributeAssertion attributeName="value" comparisonType="None"/>
|
|
550
|
+
</attributeAssertions>
|
|
551
|
+
</uiFieldAssertion>
|
|
552
|
+
</value>
|
|
553
|
+
</argument>
|
|
554
|
+
<argument id="captureAfter">
|
|
555
|
+
<value class="value" valueClass="string">false</value>
|
|
556
|
+
</argument>
|
|
557
|
+
<argument id="columnAssertions">
|
|
558
|
+
<value class="valueList" mutable="Mutable"/>
|
|
559
|
+
</argument>
|
|
560
|
+
<argument id="pageAssertions">
|
|
561
|
+
<value class="valueList" mutable="Mutable"/>
|
|
562
|
+
</argument>
|
|
563
|
+
<argument id="beforeWait"/>
|
|
564
|
+
<argument id="autoRetry"/>
|
|
565
|
+
</arguments>
|
|
566
|
+
</apiCall>
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
**Valid `comparisonType` values:** `EqualTo` | `NotEqualTo` | `Contains` | `NotContains` | `StartsWith` | `EndsWith` | `None`
|
|
570
|
+
|
|
571
|
+
### UiWithRow
|
|
572
|
+
|
|
573
|
+
Targets a specific row in a related list or table. Substeps inside the clause operate in the row context (locators can use `rowLocator` parameter for scoping).
|
|
574
|
+
|
|
575
|
+
```xml
|
|
576
|
+
<apiCall apiId="com.provar.plugins.forcedotcom.core.ui.UiWithRow"
|
|
577
|
+
name="UiWithRow" testItemId="22"
|
|
578
|
+
title="With Roles rows 1">
|
|
579
|
+
<arguments>
|
|
580
|
+
<argument id="uiConnectionName">
|
|
581
|
+
<value class="value" valueClass="string">DemoOrg</value>
|
|
582
|
+
</argument>
|
|
583
|
+
<argument id="locator">
|
|
584
|
+
<value class="uiLocator" uri="sf:ui:locator:row?table=roleBlock%2Froles"/>
|
|
585
|
+
</argument>
|
|
586
|
+
<argument id="uiRowLocator">
|
|
587
|
+
<value class="value" valueClass="string">1</value>
|
|
588
|
+
</argument>
|
|
589
|
+
<argument id="locatorDescription">
|
|
590
|
+
<value class="value" valueClass="string">With Roles rows 1</value>
|
|
591
|
+
</argument>
|
|
592
|
+
<argument id="failIfNotFound">
|
|
593
|
+
<value class="value" valueClass="boolean">true</value>
|
|
594
|
+
</argument>
|
|
595
|
+
<argument id="debugRowLocator">
|
|
596
|
+
<value class="value" valueClass="boolean">true</value>
|
|
597
|
+
</argument>
|
|
598
|
+
<argument id="resultName">
|
|
599
|
+
<value class="value" valueClass="string">Row</value>
|
|
600
|
+
</argument>
|
|
601
|
+
<argument id="resultScope">
|
|
602
|
+
<value class="value" valueClass="string">Local</value>
|
|
603
|
+
</argument>
|
|
604
|
+
</arguments>
|
|
605
|
+
<clauses>
|
|
606
|
+
<clause name="substeps" testItemId="23">
|
|
607
|
+
<steps>
|
|
608
|
+
<!-- UiDoAction steps scoped to this row -->
|
|
609
|
+
</steps>
|
|
610
|
+
</clause>
|
|
611
|
+
</clauses>
|
|
612
|
+
</apiCall>
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
**Row locator URI format:** `sf:ui:locator:row?table=RELATED_LIST_NAME`
|
|
616
|
+
|
|
617
|
+
The `uiRowLocator` can be a row number (1-based) or a field-value match expression.
|
|
618
|
+
|
|
619
|
+
### UiHandleAlert
|
|
620
|
+
|
|
621
|
+
Handles browser-level alert/confirm dialogs. Place this immediately after the step that triggers the dialog (e.g., a Delete button click).
|
|
622
|
+
|
|
623
|
+
```xml
|
|
624
|
+
<apiCall apiId="com.provar.plugins.forcedotcom.core.ui.UiHandleAlert"
|
|
625
|
+
name="UiHandleAlert" testItemId="46"
|
|
626
|
+
title="Handle UI Alerts">
|
|
627
|
+
<arguments>
|
|
628
|
+
<argument id="alerts">
|
|
629
|
+
<value class="valueList" mutable="Mutable">
|
|
630
|
+
<namedValues mutable="Mutable">
|
|
631
|
+
<namedValue name="expectedMessage"/>
|
|
632
|
+
<namedValue name="response">
|
|
633
|
+
<value class="value" valueClass="string">OK</value>
|
|
634
|
+
</namedValue>
|
|
635
|
+
<namedValue name="beforeWait"/>
|
|
636
|
+
<namedValue name="afterWait"/>
|
|
637
|
+
<namedValue name="autoRetry"/>
|
|
638
|
+
</namedValues>
|
|
639
|
+
</value>
|
|
640
|
+
</argument>
|
|
641
|
+
<argument id="captureBefore">
|
|
642
|
+
<value class="value" valueClass="string">false</value>
|
|
643
|
+
</argument>
|
|
644
|
+
<argument id="captureAfter">
|
|
645
|
+
<value class="value" valueClass="string">false</value>
|
|
646
|
+
</argument>
|
|
647
|
+
</arguments>
|
|
648
|
+
</apiCall>
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
**Valid `response` values:** `OK` | `Cancel`
|
|
652
|
+
|
|
653
|
+
Set `expectedMessage` to a string value to assert the alert text matches before responding.
|
|
654
|
+
|
|
655
|
+
---
|
|
656
|
+
|
|
657
|
+
## Apex CRUD Operations
|
|
658
|
+
|
|
659
|
+
### ApexCreateObject
|
|
660
|
+
|
|
661
|
+
Creates a Salesforce record via the API. Requires `parameterGeneratorUri`, `parameterGeneratorProperties`, and `generatedParameters` — these are always present on Apex CRUD steps and the validator checks for them.
|
|
662
|
+
|
|
663
|
+
> **`parameterGeneratorProperties` key format:** The full command class name prefix is required, e.g.
|
|
664
|
+
> `com.provar.plugins.forcedotcom.ui.commands.CreateCustomObjectTestStepCommand.ConnectionName`
|
|
665
|
+
> (not just `.ConnectionName`).
|
|
666
|
+
|
|
667
|
+
```xml
|
|
668
|
+
<apiCall apiId="com.provar.plugins.forcedotcom.core.testapis.ApexCreateObject"
|
|
669
|
+
name="ApexCreateObject"
|
|
670
|
+
parameterGeneratorUri="command:com.provar.plugins.forcedotcom.ui.commands.CreateCustomObjectTestStepCommand"
|
|
671
|
+
testItemId="3"
|
|
672
|
+
title="Create Object: Lead=>LeadId">
|
|
673
|
+
<arguments>
|
|
674
|
+
<argument id="objectType">
|
|
675
|
+
<value class="value" valueClass="string">Lead</value>
|
|
676
|
+
</argument>
|
|
677
|
+
<argument id="resultIdName">
|
|
678
|
+
<value class="value" valueClass="string">LeadId</value>
|
|
679
|
+
</argument>
|
|
680
|
+
<argument id="apexConnectionName">
|
|
681
|
+
<value class="value" valueClass="string">Admin</value>
|
|
682
|
+
</argument>
|
|
683
|
+
<argument id="resultScope">
|
|
684
|
+
<value class="value" valueClass="string">Test</value>
|
|
685
|
+
</argument>
|
|
686
|
+
<argument id="LastName">
|
|
687
|
+
<value class="value" valueClass="string">Smith</value>
|
|
688
|
+
</argument>
|
|
689
|
+
<argument id="Company">
|
|
690
|
+
<value class="value" valueClass="string">Acme</value>
|
|
691
|
+
</argument>
|
|
692
|
+
</arguments>
|
|
693
|
+
<parameterGeneratorProperties>
|
|
694
|
+
<propertyValue name="com.provar.plugins.forcedotcom.ui.commands.CreateCustomObjectTestStepCommand.ConnectionName">Admin</propertyValue>
|
|
695
|
+
<propertyValue name="com.provar.plugins.forcedotcom.ui.commands.CreateCustomObjectTestStepCommand.CustomObjectName">Lead</propertyValue>
|
|
696
|
+
</parameterGeneratorProperties>
|
|
697
|
+
<generatedParameters>
|
|
698
|
+
<apiParam group="fields" modelBinding="sf:ui:binding:object?object=Lead&field=LastName" name="LastName" title="LastName"/>
|
|
699
|
+
<apiParam group="fields" modelBinding="sf:ui:binding:object?object=Lead&field=Company" name="Company" title="Company"/>
|
|
700
|
+
</generatedParameters>
|
|
701
|
+
</apiCall>
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
### ApexReadObject
|
|
705
|
+
|
|
706
|
+
Reads fields from an existing record by ID. `objectId` takes a variable reference to an ID stored from a prior `ApexCreateObject` or `sfUiTargetResultName` capture.
|
|
707
|
+
|
|
708
|
+
```xml
|
|
709
|
+
<apiCall apiId="com.provar.plugins.forcedotcom.core.testapis.ApexReadObject"
|
|
710
|
+
name="ApexReadObject"
|
|
711
|
+
parameterGeneratorUri="command:com.provar.plugins.forcedotcom.ui.commands.ReadCustomObjectTestStepCommand"
|
|
712
|
+
testItemId="1"
|
|
713
|
+
title="Read Object: Account = {AccountId}">
|
|
714
|
+
<arguments>
|
|
715
|
+
<argument id="apexConnectionName">
|
|
716
|
+
<value class="value" valueClass="string">Admin</value>
|
|
717
|
+
</argument>
|
|
718
|
+
<argument id="objectType">
|
|
719
|
+
<value class="value" valueClass="string">Account</value>
|
|
720
|
+
</argument>
|
|
721
|
+
<argument id="objectId">
|
|
722
|
+
<value class="variable">
|
|
723
|
+
<path element="AccountId"/>
|
|
724
|
+
</value>
|
|
725
|
+
</argument>
|
|
726
|
+
<argument id="resultName">
|
|
727
|
+
<value class="value" valueClass="string">AccountRecord</value>
|
|
728
|
+
</argument>
|
|
729
|
+
</arguments>
|
|
730
|
+
<parameterGeneratorProperties>
|
|
731
|
+
<propertyValue name="com.provar.plugins.forcedotcom.ui.commands.ReadCustomObjectTestStepCommand.ConnectionName">Admin</propertyValue>
|
|
732
|
+
<propertyValue name="com.provar.plugins.forcedotcom.ui.commands.ReadCustomObjectTestStepCommand.CustomObjectName">Account</propertyValue>
|
|
733
|
+
</parameterGeneratorProperties>
|
|
734
|
+
<generatedParameters>
|
|
735
|
+
<apiParam group="fields" modelBinding="sf:ui:binding:object?object=Account&field=Name" name="Name" title="Name"/>
|
|
736
|
+
<apiParam group="fields" modelBinding="sf:ui:binding:object?object=Account&field=Phone" name="Phone" title="Phone"/>
|
|
737
|
+
</generatedParameters>
|
|
738
|
+
</apiCall>
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
### ApexUpdateObject
|
|
742
|
+
|
|
743
|
+
Updates fields on an existing record. `objectId` is required and must reference a variable.
|
|
744
|
+
|
|
745
|
+
```xml
|
|
746
|
+
<apiCall apiId="com.provar.plugins.forcedotcom.core.testapis.ApexUpdateObject"
|
|
747
|
+
name="ApexUpdateObject"
|
|
748
|
+
parameterGeneratorUri="command:com.provar.plugins.forcedotcom.ui.commands.UpdateCustomObjectTestStepCommand"
|
|
749
|
+
testItemId="1"
|
|
750
|
+
title="Update Object: Account = {AccountId}">
|
|
751
|
+
<arguments>
|
|
752
|
+
<argument id="apexConnectionName">
|
|
753
|
+
<value class="value" valueClass="string">Admin</value>
|
|
754
|
+
</argument>
|
|
755
|
+
<argument id="objectType">
|
|
756
|
+
<value class="value" valueClass="string">Account</value>
|
|
757
|
+
</argument>
|
|
758
|
+
<argument id="objectId">
|
|
759
|
+
<value class="variable">
|
|
760
|
+
<path element="AccountId"/>
|
|
761
|
+
</value>
|
|
762
|
+
</argument>
|
|
763
|
+
<argument id="Industry">
|
|
764
|
+
<value class="value" valueClass="string">Technology</value>
|
|
765
|
+
</argument>
|
|
766
|
+
</arguments>
|
|
767
|
+
<parameterGeneratorProperties>
|
|
768
|
+
<propertyValue name="com.provar.plugins.forcedotcom.ui.commands.UpdateCustomObjectTestStepCommand.ConnectionName">Admin</propertyValue>
|
|
769
|
+
<propertyValue name="com.provar.plugins.forcedotcom.ui.commands.UpdateCustomObjectTestStepCommand.CustomObjectName">Account</propertyValue>
|
|
770
|
+
</parameterGeneratorProperties>
|
|
771
|
+
<generatedParameters>
|
|
772
|
+
<apiParam group="fields" modelBinding="sf:ui:binding:object?object=Account&field=Industry" name="Industry" title="Industry"/>
|
|
773
|
+
</generatedParameters>
|
|
774
|
+
</apiCall>
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
### ApexDeleteObject
|
|
778
|
+
|
|
779
|
+
Deletes a record by ID. No `parameterGeneratorUri` required.
|
|
780
|
+
|
|
781
|
+
```xml
|
|
782
|
+
<apiCall apiId="com.provar.plugins.forcedotcom.core.testapis.ApexDeleteObject"
|
|
783
|
+
name="ApexDeleteObject" testItemId="1"
|
|
784
|
+
title="Delete Object: {AccountId}">
|
|
785
|
+
<arguments>
|
|
786
|
+
<argument id="apexConnectionName">
|
|
787
|
+
<value class="value" valueClass="string">Admin</value>
|
|
788
|
+
</argument>
|
|
789
|
+
<argument id="objectId">
|
|
790
|
+
<value class="variable">
|
|
791
|
+
<path element="AccountId"/>
|
|
792
|
+
</value>
|
|
793
|
+
</argument>
|
|
794
|
+
</arguments>
|
|
795
|
+
</apiCall>
|
|
796
|
+
```
|
|
797
|
+
|
|
798
|
+
### ApexSoqlQuery
|
|
799
|
+
|
|
800
|
+
Runs a SOQL query and stores results as a list variable. Always include `Id` and `Name` in the SELECT clause. Always specify `resultListName` and `resultScope`.
|
|
801
|
+
|
|
802
|
+
```xml
|
|
803
|
+
<apiCall apiId="com.provar.plugins.forcedotcom.core.testapis.ApexSoqlQuery"
|
|
804
|
+
name="ApexSoqlQuery" testItemId="1"
|
|
805
|
+
title="SOQL Query: SELECT Id, Name FROM Account=>AccountRows">
|
|
806
|
+
<arguments>
|
|
807
|
+
<argument id="apexConnectionName">
|
|
808
|
+
<value class="value" valueClass="string">Admin</value>
|
|
809
|
+
</argument>
|
|
810
|
+
<argument id="soqlQuery">
|
|
811
|
+
<value class="value" valueClass="string">SELECT Id, Name FROM Account WHERE Name = 'Test Account'</value>
|
|
812
|
+
</argument>
|
|
813
|
+
<argument id="resultListName">
|
|
814
|
+
<value class="value" valueClass="string">AccountRows</value>
|
|
815
|
+
</argument>
|
|
816
|
+
<argument id="resultScope">
|
|
817
|
+
<value class="value" valueClass="string">Test</value>
|
|
818
|
+
</argument>
|
|
819
|
+
</arguments>
|
|
820
|
+
</apiCall>
|
|
821
|
+
```
|
|
822
|
+
|
|
823
|
+
---
|
|
824
|
+
|
|
825
|
+
## Control Flow
|
|
826
|
+
|
|
827
|
+
### SetValues
|
|
828
|
+
|
|
829
|
+
Sets one or more test variables. Use this for all test data instead of hardcoding values across multiple steps. Variable names must match `^[A-Za-z_][A-Za-z0-9_]*$`.
|
|
830
|
+
|
|
831
|
+
> **`dataTable` binding is ignored by the CLI.** Always use `SetValues` for parameterized data when tests
|
|
832
|
+
> run via `sf provar automation testrun` or Quality Hub.
|
|
833
|
+
|
|
834
|
+
```xml
|
|
835
|
+
<apiCall apiId="com.provar.plugins.bundled.apis.control.SetValues"
|
|
836
|
+
name="SetValues" testItemId="1"
|
|
837
|
+
title="Set Test Data Variables">
|
|
838
|
+
<arguments>
|
|
839
|
+
<argument id="values">
|
|
840
|
+
<value class="valueList" mutable="Mutable">
|
|
841
|
+
<namedValues mutable="Mutable">
|
|
842
|
+
<namedValue name="AccountName">
|
|
843
|
+
<value class="value" valueClass="string">Acme Corporation</value>
|
|
844
|
+
</namedValue>
|
|
845
|
+
<namedValue name="PhoneNumber">
|
|
846
|
+
<value class="value" valueClass="string">555-123-4567</value>
|
|
847
|
+
</namedValue>
|
|
848
|
+
<namedValue name="IsActive">
|
|
849
|
+
<value class="value" valueClass="boolean">true</value>
|
|
850
|
+
</namedValue>
|
|
851
|
+
</namedValues>
|
|
852
|
+
</value>
|
|
853
|
+
</argument>
|
|
854
|
+
</arguments>
|
|
855
|
+
</apiCall>
|
|
856
|
+
```
|
|
857
|
+
|
|
858
|
+
### StepGroup
|
|
859
|
+
|
|
860
|
+
Groups steps with a shared label. Substeps go in `<clause name="hidden">`.
|
|
861
|
+
|
|
862
|
+
```xml
|
|
863
|
+
<apiCall apiId="com.provar.plugins.bundled.apis.control.StepGroup"
|
|
864
|
+
name="StepGroup" testItemId="1"
|
|
865
|
+
title="Setup - Create Connection">
|
|
866
|
+
<arguments>
|
|
867
|
+
<argument id="description">
|
|
868
|
+
<value class="value" valueClass="string">Establish connection to Salesforce</value>
|
|
869
|
+
</argument>
|
|
870
|
+
</arguments>
|
|
871
|
+
<clauses>
|
|
872
|
+
<clause name="hidden" testItemId="2">
|
|
873
|
+
<steps>
|
|
874
|
+
<!-- Steps go here -->
|
|
875
|
+
</steps>
|
|
876
|
+
</clause>
|
|
877
|
+
</clauses>
|
|
878
|
+
</apiCall>
|
|
879
|
+
```
|
|
880
|
+
|
|
881
|
+
### If
|
|
882
|
+
|
|
883
|
+
```xml
|
|
884
|
+
<apiCall apiId="com.provar.plugins.bundled.apis.If"
|
|
885
|
+
name="If" testItemId="1"
|
|
886
|
+
title="If: {IsActive}">
|
|
887
|
+
<arguments>
|
|
888
|
+
<argument id="condition">
|
|
889
|
+
<value class="value" valueClass="string">{IsActive} == true</value>
|
|
890
|
+
</argument>
|
|
891
|
+
</arguments>
|
|
892
|
+
<clauses>
|
|
893
|
+
<clause name="then" testItemId="2">
|
|
894
|
+
<steps>
|
|
895
|
+
<!-- Steps if condition is true -->
|
|
896
|
+
</steps>
|
|
897
|
+
</clause>
|
|
898
|
+
<clause name="else" testItemId="3">
|
|
899
|
+
<steps>
|
|
900
|
+
<!-- Steps if condition is false -->
|
|
901
|
+
</steps>
|
|
902
|
+
</clause>
|
|
903
|
+
</clauses>
|
|
904
|
+
</apiCall>
|
|
905
|
+
```
|
|
906
|
+
|
|
907
|
+
### ForEach
|
|
908
|
+
|
|
909
|
+
Iterates over a list variable. `list` must reference an existing variable. `valueName` must be unique within scope.
|
|
910
|
+
|
|
911
|
+
```xml
|
|
912
|
+
<apiCall apiId="com.provar.plugins.bundled.apis.control.ForEach"
|
|
913
|
+
name="ForEach" testItemId="1"
|
|
914
|
+
title="For Each: {AccountRows}=>CurrentRow">
|
|
915
|
+
<arguments>
|
|
916
|
+
<argument id="list">
|
|
917
|
+
<value class="variable">
|
|
918
|
+
<path element="AccountRows"/>
|
|
919
|
+
</value>
|
|
920
|
+
</argument>
|
|
921
|
+
<argument id="fromItem">
|
|
922
|
+
<value class="value" valueClass="decimal">1</value>
|
|
923
|
+
</argument>
|
|
924
|
+
<argument id="valueName">
|
|
925
|
+
<value class="value" valueClass="string">CurrentRow</value>
|
|
926
|
+
</argument>
|
|
927
|
+
<argument id="continueOnFailure">
|
|
928
|
+
<value class="value" valueClass="boolean">false</value>
|
|
929
|
+
</argument>
|
|
930
|
+
</arguments>
|
|
931
|
+
<clauses>
|
|
932
|
+
<clause name="substeps" testItemId="2">
|
|
933
|
+
<steps>
|
|
934
|
+
<!-- Loop body -->
|
|
935
|
+
</steps>
|
|
936
|
+
</clause>
|
|
937
|
+
</clauses>
|
|
938
|
+
</apiCall>
|
|
939
|
+
```
|
|
940
|
+
|
|
941
|
+
### TryCatchFinally
|
|
942
|
+
|
|
943
|
+
Wraps steps with error handling. The `finally` clause always runs, making it the right place for cleanup steps (e.g., delete records created during the test).
|
|
944
|
+
|
|
945
|
+
```xml
|
|
946
|
+
<apiCall apiId="com.provar.plugins.bundled.apis.control.TryCatchFinally"
|
|
947
|
+
name="TryCatchFinally" testItemId="1"
|
|
948
|
+
title="Try/Catch/Finally">
|
|
949
|
+
<clauses>
|
|
950
|
+
<clause name="try" testItemId="2">
|
|
951
|
+
<steps>
|
|
952
|
+
<!-- Main test steps -->
|
|
953
|
+
</steps>
|
|
954
|
+
</clause>
|
|
955
|
+
<clause name="catch" testItemId="3">
|
|
956
|
+
<steps>
|
|
957
|
+
<!-- Steps to run on failure (optional) -->
|
|
958
|
+
</steps>
|
|
959
|
+
</clause>
|
|
960
|
+
<clause name="finally" testItemId="4">
|
|
961
|
+
<steps>
|
|
962
|
+
<!-- Cleanup: always runs, even on failure -->
|
|
963
|
+
</steps>
|
|
964
|
+
</clause>
|
|
965
|
+
</clauses>
|
|
966
|
+
</apiCall>
|
|
967
|
+
```
|
|
968
|
+
|
|
969
|
+
### WaitFor
|
|
970
|
+
|
|
971
|
+
Polls a condition at intervals until true or max iterations are reached.
|
|
972
|
+
|
|
973
|
+
```xml
|
|
974
|
+
<apiCall apiId="com.provar.plugins.bundled.apis.control.WaitFor"
|
|
975
|
+
name="WaitFor" testItemId="1"
|
|
976
|
+
title="Wait For: {IsComplete}">
|
|
977
|
+
<arguments>
|
|
978
|
+
<argument id="condition">
|
|
979
|
+
<value class="value" valueClass="string">{IsComplete} == true</value>
|
|
980
|
+
</argument>
|
|
981
|
+
<argument id="testAtStart">
|
|
982
|
+
<value class="value" valueClass="boolean">true</value>
|
|
983
|
+
</argument>
|
|
984
|
+
<argument id="maxIterations">
|
|
985
|
+
<value class="value" valueClass="decimal">10</value>
|
|
986
|
+
</argument>
|
|
987
|
+
<argument id="sleepSecs">
|
|
988
|
+
<value class="value" valueClass="decimal">2</value>
|
|
989
|
+
</argument>
|
|
990
|
+
<argument id="continueOnFailure">
|
|
991
|
+
<value class="value" valueClass="boolean">false</value>
|
|
992
|
+
</argument>
|
|
993
|
+
</arguments>
|
|
994
|
+
<clauses>
|
|
995
|
+
<clause name="substeps" testItemId="2">
|
|
996
|
+
<steps>
|
|
997
|
+
<!-- Steps to check the condition -->
|
|
998
|
+
</steps>
|
|
999
|
+
</clause>
|
|
1000
|
+
</clauses>
|
|
1001
|
+
</apiCall>
|
|
1002
|
+
```
|
|
1003
|
+
|
|
1004
|
+
> **Rule CONTROL-WAITFOR-002:** `maxIterations` is required — omitting it produces an infinite loop.
|
|
1005
|
+
|
|
1006
|
+
### Sleep
|
|
1007
|
+
|
|
1008
|
+
```xml
|
|
1009
|
+
<apiCall apiId="com.provar.plugins.bundled.apis.control.Sleep"
|
|
1010
|
+
name="Sleep" testItemId="1"
|
|
1011
|
+
title="Sleep for 5 seconds">
|
|
1012
|
+
<arguments>
|
|
1013
|
+
<argument id="sleepSecs">
|
|
1014
|
+
<value class="value" valueClass="decimal">5</value>
|
|
1015
|
+
</argument>
|
|
1016
|
+
</arguments>
|
|
1017
|
+
</apiCall>
|
|
1018
|
+
```
|
|
1019
|
+
|
|
1020
|
+
### CallTest
|
|
1021
|
+
|
|
1022
|
+
Calls another test case as a step (callable tests have `visibility="Internal"`). Use this to share setup logic across test cases.
|
|
1023
|
+
|
|
1024
|
+
```xml
|
|
1025
|
+
<apiCall apiId="com.provar.plugins.bundled.apis.control.CallTest"
|
|
1026
|
+
name="CallTest" testItemId="1"
|
|
1027
|
+
title="Call: Create Lead API">
|
|
1028
|
+
<arguments>
|
|
1029
|
+
<argument id="testCase">
|
|
1030
|
+
<value class="value" valueClass="string">Callables/Create Lead API</value>
|
|
1031
|
+
</argument>
|
|
1032
|
+
<argument id="LastName">
|
|
1033
|
+
<value class="value" valueClass="string">Smith</value>
|
|
1034
|
+
</argument>
|
|
1035
|
+
<argument id="Company">
|
|
1036
|
+
<value class="value" valueClass="string">Acme</value>
|
|
1037
|
+
</argument>
|
|
1038
|
+
</arguments>
|
|
1039
|
+
</apiCall>
|
|
1040
|
+
```
|
|
1041
|
+
|
|
1042
|
+
---
|
|
1043
|
+
|
|
1044
|
+
## Assertions
|
|
1045
|
+
|
|
1046
|
+
### AssertValues
|
|
1047
|
+
|
|
1048
|
+
Variable-to-variable or variable-to-literal comparison. For UI field assertions use `UiAssert` instead.
|
|
1049
|
+
|
|
1050
|
+
```xml
|
|
1051
|
+
<apiCall apiId="com.provar.plugins.bundled.apis.AssertValues"
|
|
1052
|
+
name="AssertValues" testItemId="1"
|
|
1053
|
+
title="Assert: {Expected} EqualTo {Actual}">
|
|
1054
|
+
<arguments>
|
|
1055
|
+
<argument id="expectedValue">
|
|
1056
|
+
<value class="variable">
|
|
1057
|
+
<path element="ExpectedValue"/>
|
|
1058
|
+
</value>
|
|
1059
|
+
</argument>
|
|
1060
|
+
<argument id="comparisonType">
|
|
1061
|
+
<value class="value" valueClass="string">EqualTo</value>
|
|
1062
|
+
</argument>
|
|
1063
|
+
<argument id="actualValue">
|
|
1064
|
+
<value class="variable">
|
|
1065
|
+
<path element="ActualValue"/>
|
|
1066
|
+
</value>
|
|
1067
|
+
</argument>
|
|
1068
|
+
<argument id="caseSensitive">
|
|
1069
|
+
<value class="value" valueClass="boolean">false</value>
|
|
1070
|
+
</argument>
|
|
1071
|
+
<argument id="numeric">
|
|
1072
|
+
<value class="value" valueClass="boolean">false</value>
|
|
1073
|
+
</argument>
|
|
1074
|
+
<argument id="failureMessage">
|
|
1075
|
+
<value class="value" valueClass="string">Values do not match</value>
|
|
1076
|
+
</argument>
|
|
1077
|
+
</arguments>
|
|
1078
|
+
</apiCall>
|
|
1079
|
+
```
|
|
1080
|
+
|
|
1081
|
+
---
|
|
1082
|
+
|
|
1083
|
+
## BDD Steps
|
|
1084
|
+
|
|
1085
|
+
`Given`, `When`, `Then`, `And`, `But` all share the same structure: a `description` argument and a `hidden` clause for substeps. Use them to add a BDD narrative layer over standard steps.
|
|
1086
|
+
|
|
1087
|
+
```xml
|
|
1088
|
+
<apiCall apiId="com.provar.plugins.bundled.apis.bdd.Given"
|
|
1089
|
+
name="Given" testItemId="1"
|
|
1090
|
+
title="Given: The user is logged in to Salesforce">
|
|
1091
|
+
<arguments>
|
|
1092
|
+
<argument id="description">
|
|
1093
|
+
<value class="value" valueClass="string">The user is logged in to Salesforce</value>
|
|
1094
|
+
</argument>
|
|
1095
|
+
</arguments>
|
|
1096
|
+
<clauses>
|
|
1097
|
+
<clause name="hidden" testItemId="2">
|
|
1098
|
+
<steps>
|
|
1099
|
+
<!-- ApexConnect or UiConnect steps go here -->
|
|
1100
|
+
</steps>
|
|
1101
|
+
</clause>
|
|
1102
|
+
</clauses>
|
|
1103
|
+
</apiCall>
|
|
1104
|
+
|
|
1105
|
+
<!-- And / But follow the same structure -->
|
|
1106
|
+
<apiCall apiId="com.provar.plugins.bundled.apis.bdd.And"
|
|
1107
|
+
name="And" testItemId="5"
|
|
1108
|
+
title="And: The opportunity stage is set to Closed Won">
|
|
1109
|
+
<arguments>
|
|
1110
|
+
<argument id="description">
|
|
1111
|
+
<value class="value" valueClass="string">The opportunity stage is set to Closed Won</value>
|
|
1112
|
+
</argument>
|
|
1113
|
+
</arguments>
|
|
1114
|
+
<clauses>
|
|
1115
|
+
<clause name="hidden" testItemId="6">
|
|
1116
|
+
<steps>
|
|
1117
|
+
<!-- Steps -->
|
|
1118
|
+
</steps>
|
|
1119
|
+
</clause>
|
|
1120
|
+
</clauses>
|
|
1121
|
+
</apiCall>
|
|
1122
|
+
```
|
|
1123
|
+
|
|
1124
|
+
---
|
|
1125
|
+
|
|
1126
|
+
## Database Steps
|
|
1127
|
+
|
|
1128
|
+
### DbConnect
|
|
1129
|
+
|
|
1130
|
+
```xml
|
|
1131
|
+
<apiCall apiId="com.provar.plugins.bundled.apis.db.DbConnect"
|
|
1132
|
+
name="DbConnect" testItemId="1"
|
|
1133
|
+
title="DB Connect: DbConnection">
|
|
1134
|
+
<arguments>
|
|
1135
|
+
<argument id="connectionName">
|
|
1136
|
+
<value class="value" valueClass="string">MyDatabase</value>
|
|
1137
|
+
</argument>
|
|
1138
|
+
<argument id="connectionId">
|
|
1139
|
+
<value class="value" valueClass="string">database-connection-id</value>
|
|
1140
|
+
</argument>
|
|
1141
|
+
<argument id="autoCommit">
|
|
1142
|
+
<value class="value" valueClass="boolean">true</value>
|
|
1143
|
+
</argument>
|
|
1144
|
+
<argument id="resultName">
|
|
1145
|
+
<value class="value" valueClass="string">DbConnection</value>
|
|
1146
|
+
</argument>
|
|
1147
|
+
<argument id="resultScope">
|
|
1148
|
+
<value class="value" valueClass="string">Test</value>
|
|
1149
|
+
</argument>
|
|
1150
|
+
</arguments>
|
|
1151
|
+
</apiCall>
|
|
1152
|
+
```
|
|
1153
|
+
|
|
1154
|
+
### SqlQuery
|
|
1155
|
+
|
|
1156
|
+
```xml
|
|
1157
|
+
<apiCall apiId="com.provar.plugins.bundled.apis.db.SqlQuery"
|
|
1158
|
+
name="SqlQuery" testItemId="1"
|
|
1159
|
+
title="SQL Query: DbConnection=>DbResults">
|
|
1160
|
+
<arguments>
|
|
1161
|
+
<argument id="dbConnectionName">
|
|
1162
|
+
<value class="value" valueClass="string">DbConnection</value>
|
|
1163
|
+
</argument>
|
|
1164
|
+
<argument id="query">
|
|
1165
|
+
<value class="value" valueClass="string">SELECT * FROM Users WHERE Status = 'Active'</value>
|
|
1166
|
+
</argument>
|
|
1167
|
+
<argument id="resultName">
|
|
1168
|
+
<value class="value" valueClass="string">DbResults</value>
|
|
1169
|
+
</argument>
|
|
1170
|
+
<argument id="resultScope">
|
|
1171
|
+
<value class="value" valueClass="string">Test</value>
|
|
1172
|
+
</argument>
|
|
1173
|
+
</arguments>
|
|
1174
|
+
</apiCall>
|
|
1175
|
+
```
|
|
1176
|
+
|
|
1177
|
+
---
|
|
1178
|
+
|
|
1179
|
+
## Web Service Steps
|
|
1180
|
+
|
|
1181
|
+
### WebConnect
|
|
1182
|
+
|
|
1183
|
+
```xml
|
|
1184
|
+
<apiCall apiId="com.provar.plugins.bundled.apis.restservice.WebConnect"
|
|
1185
|
+
name="WebConnect" testItemId="1"
|
|
1186
|
+
title="Web Connect: WebServiceConnection">
|
|
1187
|
+
<arguments>
|
|
1188
|
+
<argument id="connectionName">
|
|
1189
|
+
<value class="value" valueClass="string">MyWebService</value>
|
|
1190
|
+
</argument>
|
|
1191
|
+
<argument id="connectionId">
|
|
1192
|
+
<value class="value" valueClass="string">web-service-connection-id</value>
|
|
1193
|
+
</argument>
|
|
1194
|
+
<argument id="resultName">
|
|
1195
|
+
<value class="value" valueClass="string">WebServiceConnection</value>
|
|
1196
|
+
</argument>
|
|
1197
|
+
<argument id="resultScope">
|
|
1198
|
+
<value class="value" valueClass="string">Test</value>
|
|
1199
|
+
</argument>
|
|
1200
|
+
</arguments>
|
|
1201
|
+
</apiCall>
|
|
1202
|
+
```
|
|
1203
|
+
|
|
1204
|
+
### RestRequest
|
|
1205
|
+
|
|
1206
|
+
```xml
|
|
1207
|
+
<apiCall apiId="com.provar.plugins.bundled.apis.restservice.RestRequest"
|
|
1208
|
+
name="RestRequest" testItemId="1"
|
|
1209
|
+
title="Web Request (REST): GET /api/users=>RestResponse">
|
|
1210
|
+
<arguments>
|
|
1211
|
+
<argument id="connectionName">
|
|
1212
|
+
<value class="value" valueClass="string">WebServiceConnection</value>
|
|
1213
|
+
</argument>
|
|
1214
|
+
<argument id="targetValue">
|
|
1215
|
+
<value class="value" valueClass="string">GET</value>
|
|
1216
|
+
</argument>
|
|
1217
|
+
<argument id="resultName">
|
|
1218
|
+
<value class="value" valueClass="string">RestResponse</value>
|
|
1219
|
+
</argument>
|
|
1220
|
+
<argument id="resultScope">
|
|
1221
|
+
<value class="value" valueClass="string">Test</value>
|
|
1222
|
+
</argument>
|
|
1223
|
+
<argument id="statusResultName">
|
|
1224
|
+
<value class="value" valueClass="string">RestStatus</value>
|
|
1225
|
+
</argument>
|
|
1226
|
+
<argument id="restResourceUrl">
|
|
1227
|
+
<value class="value" valueClass="string">/api/users</value>
|
|
1228
|
+
</argument>
|
|
1229
|
+
</arguments>
|
|
1230
|
+
</apiCall>
|
|
1231
|
+
```
|
|
1232
|
+
|
|
1233
|
+
---
|
|
1234
|
+
|
|
1235
|
+
## Value Types Reference
|
|
1236
|
+
|
|
1237
|
+
```xml
|
|
1238
|
+
<!-- String literal -->
|
|
1239
|
+
<value class="value" valueClass="string">Text content</value>
|
|
1240
|
+
|
|
1241
|
+
<!-- Boolean -->
|
|
1242
|
+
<value class="value" valueClass="boolean">true</value>
|
|
1243
|
+
|
|
1244
|
+
<!-- Number -->
|
|
1245
|
+
<value class="value" valueClass="decimal">123.45</value>
|
|
1246
|
+
|
|
1247
|
+
<!-- GUID / record ID — required for connectionId on ApexConnect -->
|
|
1248
|
+
<value class="value" valueClass="id">74c34c63-ad34-43d9-bb12-cd783bd9bcdd</value>
|
|
1249
|
+
|
|
1250
|
+
<!-- Variable reference -->
|
|
1251
|
+
<value class="variable">
|
|
1252
|
+
<path element="VariableName"/>
|
|
1253
|
+
</value>
|
|
1254
|
+
|
|
1255
|
+
<!-- Nested object field access -->
|
|
1256
|
+
<value class="variable">
|
|
1257
|
+
<path element="ObjectName"/>
|
|
1258
|
+
<path element="FieldName"/>
|
|
1259
|
+
</value>
|
|
1260
|
+
|
|
1261
|
+
<!-- String concatenation (compound) -->
|
|
1262
|
+
<value class="compound">
|
|
1263
|
+
<parts>
|
|
1264
|
+
<value class="value" valueClass="string">Prefix </value>
|
|
1265
|
+
<value class="variable">
|
|
1266
|
+
<path element="DynamicPart"/>
|
|
1267
|
+
</value>
|
|
1268
|
+
<value class="value" valueClass="string"> suffix</value>
|
|
1269
|
+
</parts>
|
|
1270
|
+
</value>
|
|
1271
|
+
|
|
1272
|
+
<!-- UI wait (use on beforeWait / afterWait) -->
|
|
1273
|
+
<value class="uiWait" uri="default"/>
|
|
1274
|
+
|
|
1275
|
+
<!-- UI wait with custom timeout (use on autoRetry) -->
|
|
1276
|
+
<value class="uiWait" uri="ui:wait:autoRetry:timeout=10"/>
|
|
1277
|
+
```
|
|
1278
|
+
|
|
1279
|
+
---
|
|
1280
|
+
|
|
1281
|
+
## Callable Test Structure
|
|
1282
|
+
|
|
1283
|
+
A callable test (used by `CallTest`) declares its interface via `<params>`, `<outputParams>`, `<args>`, and `<outputArgs>` elements. Set `visibility="Internal"` on the `<testCase>` root.
|
|
1284
|
+
|
|
1285
|
+
```xml
|
|
1286
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
1287
|
+
<testCase guid="..." visibility="Internal">
|
|
1288
|
+
<summary/>
|
|
1289
|
+
<steps>
|
|
1290
|
+
<!-- Steps that use input params as variables -->
|
|
1291
|
+
</steps>
|
|
1292
|
+
<params>
|
|
1293
|
+
<param name="LastName" title="Last Name" passwordVariableAllowed="true">
|
|
1294
|
+
<summary/>
|
|
1295
|
+
</param>
|
|
1296
|
+
</params>
|
|
1297
|
+
<outputParams>
|
|
1298
|
+
<param name="RecordId" title="Record Id" passwordVariableAllowed="true">
|
|
1299
|
+
<summary/>
|
|
1300
|
+
<sourceValue class="variable">
|
|
1301
|
+
<path element="RecordId"/>
|
|
1302
|
+
</sourceValue>
|
|
1303
|
+
</param>
|
|
1304
|
+
</outputParams>
|
|
1305
|
+
<args>
|
|
1306
|
+
<argument id="LastName"/>
|
|
1307
|
+
</args>
|
|
1308
|
+
<outputArgs>
|
|
1309
|
+
<outputArgument id="RecordId">
|
|
1310
|
+
<name class="value" valueClass="string">RecordId</name>
|
|
1311
|
+
</outputArgument>
|
|
1312
|
+
</outputArgs>
|
|
1313
|
+
</testCase>
|
|
1314
|
+
```
|
|
1315
|
+
|
|
1316
|
+
---
|
|
1317
|
+
|
|
1318
|
+
## Validation Checklist
|
|
1319
|
+
|
|
1320
|
+
- [ ] **API IDs** — exact match from the reference table above (no variations, no `<UI4SF:*>` elements)
|
|
1321
|
+
- [ ] **Connections** — first step is `ApexConnect` or `UiConnect`; `resultName` is referenced consistently by all subsequent steps
|
|
1322
|
+
- [ ] **`connectionId`** — uses `valueClass="id"` (GUID), not `valueClass="string"`
|
|
1323
|
+
- [ ] **UI nesting** — `UiDoAction` and `UiAssert` are always inside `<clause name="substeps">` of a `UiWithScreen`
|
|
1324
|
+
- [ ] **First UiWithScreen** — `navigate` is `Always` or `IfNecessary`, never `Dont`
|
|
1325
|
+
- [ ] **UiWithScreen on Edit/View with `navigate=Always`** — includes `sfUiTargetObjectId` referencing a variable
|
|
1326
|
+
- [ ] **UiAssert required arguments** — `columnAssertions`, `pageAssertions`, `resultScope`, `captureAfter`, `beforeWait`, `autoRetry` all present (may be empty)
|
|
1327
|
+
- [ ] **UiAssert no generatedParameters** — do not add a `<generatedParameters>` block to `UiAssert`
|
|
1328
|
+
- [ ] **UiConnect arguments** — does NOT include `autoCleanup`, `quickUiLogin`, `closeAllPrimaryTabs`, `alreadyOpenBehaviour`, `lightningMode`, `uiApplicationName`, `cleanupConnectionName`
|
|
1329
|
+
- [ ] **SOQL** — queries include `SELECT` and `FROM`; include `Id` and `Name`; use `resultListName`
|
|
1330
|
+
- [ ] **CRUD result capture** — `ApexCreateObject` has `resultIdName`; `ApexReadObject` has `objectId` (variable)
|
|
1331
|
+
- [ ] **CRUD generator metadata** — `ApexCreateObject`, `ApexReadObject`, `ApexUpdateObject` include `parameterGeneratorUri`, `parameterGeneratorProperties`, and `generatedParameters`
|
|
1332
|
+
- [ ] **Variable definition** — variables used as `<value class="variable">` are defined by a prior step in scope
|
|
1333
|
+
- [ ] **Control flow** — `If` has `condition`; `ForEach` has `list` and `valueName`; `WaitFor` has `maxIterations`
|
|
1334
|
+
- [ ] **SetValues structure** — `values` argument contains `<value class="valueList">` wrapping `<namedValues>` wrapping `<namedValue>` elements
|
|
1335
|
+
- [ ] **Data types** — booleans are string `"true"`/`"false"` inside `valueClass="boolean"`; numbers use `valueClass="decimal"`
|
|
1336
|
+
- [ ] **Cleanup** — either `autoCleanup="true"` on the connection, or explicit `ApexDeleteObject` / `TryCatchFinally` finally block
|
|
1337
|
+
- [ ] **No hallucinated arguments** — see the Common AI Hallucinations table at the top of this doc
|