@provartesting/provardx-cli 1.5.2 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +5 -37
  2. package/lib/commands/provar/automation/project/validate.js +5 -3
  3. package/lib/commands/provar/automation/project/validate.js.map +1 -1
  4. package/lib/mcp/docs/PROVAR_TEST_STEP_REFERENCE.md +269 -79
  5. package/lib/mcp/docs/VALIDATION_RULE_REGISTRY.md +225 -0
  6. package/lib/mcp/prompts/loopPrompts.js +4 -3
  7. package/lib/mcp/prompts/loopPrompts.js.map +1 -1
  8. package/lib/mcp/rules/comparisonTypeSets.d.ts +21 -0
  9. package/lib/mcp/rules/comparisonTypeSets.js +45 -0
  10. package/lib/mcp/rules/comparisonTypeSets.js.map +1 -0
  11. package/lib/mcp/rules/provar_best_practices_rules.json +178 -8
  12. package/lib/mcp/rules/provar_layer1_rules.json +151 -0
  13. package/lib/mcp/rules/provar_test_step_schema.json +3005 -0
  14. package/lib/mcp/server.d.ts +15 -0
  15. package/lib/mcp/server.js +64 -1
  16. package/lib/mcp/server.js.map +1 -1
  17. package/lib/mcp/tools/automationTools.js +38 -1
  18. package/lib/mcp/tools/automationTools.js.map +1 -1
  19. package/lib/mcp/tools/bestPracticesEngine.js +1368 -10
  20. package/lib/mcp/tools/bestPracticesEngine.js.map +1 -1
  21. package/lib/mcp/tools/hierarchyValidate.d.ts +2 -1
  22. package/lib/mcp/tools/hierarchyValidate.js +7 -1
  23. package/lib/mcp/tools/hierarchyValidate.js.map +1 -1
  24. package/lib/mcp/tools/projectValidateFromPath.js +1 -2
  25. package/lib/mcp/tools/projectValidateFromPath.js.map +1 -1
  26. package/lib/mcp/tools/sfSpawn.d.ts +23 -0
  27. package/lib/mcp/tools/sfSpawn.js +72 -1
  28. package/lib/mcp/tools/sfSpawn.js.map +1 -1
  29. package/lib/mcp/tools/testCaseGenerate.js +377 -23
  30. package/lib/mcp/tools/testCaseGenerate.js.map +1 -1
  31. package/lib/mcp/tools/testCaseValidate.d.ts +46 -0
  32. package/lib/mcp/tools/testCaseValidate.js +313 -43
  33. package/lib/mcp/tools/testCaseValidate.js.map +1 -1
  34. package/lib/mcp/tools/testPlanValidate.js +3 -2
  35. package/lib/mcp/tools/testPlanValidate.js.map +1 -1
  36. package/lib/mcp/tools/testSuiteValidate.js +3 -2
  37. package/lib/mcp/tools/testSuiteValidate.js.map +1 -1
  38. package/lib/mcp/tools/uiActionApiIds.d.ts +23 -0
  39. package/lib/mcp/tools/uiActionApiIds.js +46 -0
  40. package/lib/mcp/tools/uiActionApiIds.js.map +1 -0
  41. package/lib/mcp/utils/qualityThreshold.d.ts +8 -0
  42. package/lib/mcp/utils/qualityThreshold.js +42 -0
  43. package/lib/mcp/utils/qualityThreshold.js.map +1 -0
  44. package/lib/mcp/utils/testCaseId.d.ts +23 -0
  45. package/lib/mcp/utils/testCaseId.js +156 -0
  46. package/lib/mcp/utils/testCaseId.js.map +1 -0
  47. package/lib/services/projectValidation.js +2 -1
  48. package/lib/services/projectValidation.js.map +1 -1
  49. package/messages/sf.provar.automation.project.validate.md +1 -1
  50. package/messages/sf.provar.mcp.start.md +1 -0
  51. package/oclif.manifest.json +4 -4
  52. package/package.json +4 -2
package/README.md CHANGED
@@ -100,7 +100,7 @@ sf provar auth login
100
100
  claude mcp add provar -s user -- sf provar mcp start --allowed-paths /path/to/your/provar/project
101
101
  ```
102
102
 
103
- 📖 **[docs/mcp.md](https://github.com/ProvarTesting/provardx-cli/blob/main/docs/mcp.md) — full setup, all 35+ tools, 11 MCP prompts, troubleshooting.**
103
+ 📖 **[docs/mcp.md](https://github.com/ProvarTesting/provardx-cli/blob/main/docs/mcp.md) — full setup, all 42 tools, 6 resources, 11 MCP prompts, troubleshooting.**
104
104
 
105
105
  ---
106
106
 
@@ -251,42 +251,10 @@ DESCRIPTION
251
251
  Note: --json is not available on this command — stdout is reserved for MCP traffic.
252
252
 
253
253
  TOOLS EXPOSED
254
- provar.project.inspect — inspect project folder inventory
255
- provar.pageobject.generate — generate Java Page Object skeleton
256
- provar.pageobject.validate — validate Page Object quality (30+ rules)
257
- provar.testcase.generate — generate XML test case skeleton
258
- provar.testcase.validate — validate test case XML (validity + best-practices scores)
259
- provar.testsuite.validate — validate test suite hierarchy
260
- provar.testplan.validate — validate test plan with metadata completeness checks
261
- provar.project.validate — validate full project: cross-cutting rules, connections, environments
262
- provar.properties.generate — generate provardx-properties.json from the standard template
263
- provar.properties.read — read and parse a provardx-properties.json file
264
- provar.properties.set — update fields in a provardx-properties.json file
265
- provar.properties.validate — validate a provardx-properties.json file against the schema
266
- provar.ant.generate — generate an ANT build.xml for CI/CD pipeline execution
267
- provar.ant.validate — validate an ANT build.xml for structural correctness
268
- provar.qualityhub.connect — connect to a Quality Hub org
269
- provar.qualityhub.display — display connected Quality Hub org info
270
- provar.qualityhub.testrun — trigger a Quality Hub test run
271
- provar.qualityhub.testrun.report — poll test run status
272
- provar.qualityhub.testrun.abort — abort an in-progress test run
273
- provar.qualityhub.testcase.retrieve — retrieve test cases by user story / component
274
- provar.automation.setup — detect or download/install Provar Automation binaries
275
- provar.automation.testrun — trigger a Provar Automation test run (LOCAL)
276
- provar.automation.compile — compile Page Objects after changes
277
- provar.automation.config.load — register a provardx-properties.json as the active config (required before compile/testrun)
278
- provar.automation.metadata.download — download Salesforce metadata into the project
279
- provar.qualityhub.defect.create — create Quality Hub defects from failed test executions
280
- provar.testrun.report.locate — resolve artifact paths (JUnit.xml, HTML reports) for a completed test run
281
- provar.testrun.rca — analyse a completed test run: classify failures, extract page objects, detect pre-existing issues
282
- provar.testplan.add-instance — wire a test case into a plan suite by writing a .testinstance file
283
- provar.testplan.create-suite — create a new test suite directory with .planitem inside a plan
284
- provar.testplan.remove-instance — remove a .testinstance file from a plan suite
285
- provar.nitrox.discover — discover projects containing NitroX (Hybrid Model) page objects
286
- provar.nitrox.read — read NitroX .po.json files and return parsed content
287
- provar.nitrox.validate — validate a NitroX .po.json against schema rules
288
- provar.nitrox.generate — generate a new NitroX .po.json from a component description
289
- provar.nitrox.patch — apply a JSON merge-patch to an existing NitroX .po.json file
254
+ 42 tools across: project inspection & org describe, Page Object and test-case
255
+ authoring/validation, test-suite/plan validation, properties files, Quality Hub
256
+ (test runs, defects, corpus examples), Provar Automation, ANT build, and NitroX
257
+ components. See docs/mcp.md for the full catalogue with schemas and examples.
290
258
 
291
259
  EXAMPLES
292
260
  Start MCP server (accepts stdio connections from Claude Desktop / Cursor):
@@ -7,7 +7,7 @@
7
7
  /* eslint-disable camelcase */
8
8
  import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
9
9
  import { Messages } from '@salesforce/core';
10
- import { validateProjectFromPath, ProjectValidationError } from '../../../../services/projectValidation.js';
10
+ import { validateProjectFromPath, ProjectValidationError, } from '../../../../services/projectValidation.js';
11
11
  Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
12
12
  const messages = Messages.loadMessages('@provartesting/provardx-cli', 'sf.provar.automation.project.validate');
13
13
  export default class SfProvarAutomationProjectValidate extends SfCommand {
@@ -23,7 +23,7 @@ export default class SfProvarAutomationProjectValidate extends SfCommand {
23
23
  'quality-threshold': Flags.integer({
24
24
  char: 'q',
25
25
  summary: messages.getMessage('flags.quality-threshold.summary'),
26
- default: 80,
26
+ default: 90,
27
27
  min: 0,
28
28
  max: 100,
29
29
  }),
@@ -54,7 +54,9 @@ export default class SfProvarAutomationProjectValidate extends SfCommand {
54
54
  }
55
55
  const threshold = flags['quality-threshold'];
56
56
  if (result.quality_score < threshold) {
57
- this.error(`Quality score ${result.quality_score}/100 is below the required threshold of ${threshold}/100`, { exit: 1 });
57
+ this.error(`Quality score ${result.quality_score}/100 is below the required threshold of ${threshold}/100`, {
58
+ exit: 1,
59
+ });
58
60
  }
59
61
  return result;
60
62
  }
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../../../src/commands/provar/automation/project/validate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../../../src/commands/provar/automation/project/validate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,8BAA8B;AAC9B,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EACL,uBAAuB,EACvB,sBAAsB,GAEvB,MAAM,2CAA2C,CAAC;AAEnD,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,6BAA6B,EAAE,uCAAuC,CAAC,CAAC;AAE/G,MAAM,CAAC,OAAO,OAAO,iCAAkC,SAAQ,SAAkC;IACxF,MAAM,CAAU,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACzD,MAAM,CAAU,WAAW,GAAG,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IACjE,MAAM,CAAU,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IAE5D,MAAM,CAAU,KAAK,GAAG;QAC7B,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC;YAC3B,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,4BAA4B,CAAC;YAC1D,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE;SACvB,CAAC;QACF,mBAAmB,EAAE,KAAK,CAAC,OAAO,CAAC;YACjC,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,iCAAiC,CAAC;YAC/D,OAAO,EAAE,EAAE;YACX,GAAG,EAAE,CAAC;YACN,GAAG,EAAE,GAAG;SACT,CAAC;QACF,cAAc,EAAE,KAAK,CAAC,OAAO,CAAC;YAC5B,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,4BAA4B,CAAC;YAC1D,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,IAAI;SACd,CAAC;QACF,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC;YAC1B,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,2BAA2B,CAAC;SAC1D,CAAC;KACH,CAAC;IAEK,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;QAEtE,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,uBAAuB,CAAC;gBACrC,YAAY,EAAE,KAAK,CAAC,cAAc,CAAC;gBACnC,iBAAiB,EAAE,KAAK,CAAC,mBAAmB,CAAC;gBAC7C,YAAY,EAAE,KAAK,CAAC,cAAc,CAAC;gBACnC,WAAW,EAAE,KAAK,CAAC,aAAa,CAAC;aAClC,CAAC,CAAC;YAEH,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,IAAI,CAAC,GAAG,CACN,QAAQ,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC,CAC1G,CAAC;gBACF,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;oBACpB,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACvE,CAAC;YACH,CAAC;YAED,MAAM,SAAS,GAAG,KAAK,CAAC,mBAAmB,CAAC,CAAC;YAC7C,IAAI,MAAM,CAAC,aAAa,GAAG,SAAS,EAAE,CAAC;gBACrC,IAAI,CAAC,KAAK,CAAC,iBAAiB,MAAM,CAAC,aAAa,2CAA2C,SAAS,MAAM,EAAE;oBAC1G,IAAI,EAAE,CAAC;iBACR,CAAC,CAAC;YACL,CAAC;YAED,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,IAAI,GAAG,YAAY,sBAAsB,EAAE,CAAC;gBAC1C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;YACvC,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC"}
@@ -8,83 +8,90 @@
8
8
 
9
9
  ## API ID Reference
10
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` |
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
+ | **MS Dynamics / Power Platform** (Provar 3.0.7+) | |
17
+ | MSDynamics365Connect | `com.provar.plugins.forcedotcom.core.ui.NitroXConnect:ms-dynamics365` |
18
+ | MSDataverseConnect | `com.provar.plugins.forcedotcom.core.ui.NitroXConnect:ms-dataverse` |
19
+ | MSPowerAppConnect | `com.provar.plugins.forcedotcom.core.ui.NitroXConnect:ms-powerapp` |
20
+ | MSPowerPageConnect | `com.provar.plugins.forcedotcom.core.ui.NitroXConnect:ms-powerpage` |
21
+ | **Apex CRUD** | |
22
+ | ApexCreateObject | `com.provar.plugins.forcedotcom.core.testapis.ApexCreateObject` |
23
+ | ApexReadObject | `com.provar.plugins.forcedotcom.core.testapis.ApexReadObject` |
24
+ | ApexUpdateObject | `com.provar.plugins.forcedotcom.core.testapis.ApexUpdateObject` |
25
+ | ApexDeleteObject | `com.provar.plugins.forcedotcom.core.testapis.ApexDeleteObject` |
26
+ | ApexSoqlQuery | `com.provar.plugins.forcedotcom.core.testapis.ApexSoqlQuery` |
27
+ | **Apex Advanced** | |
28
+ | ApexBulk | `com.provar.plugins.forcedotcom.core.testapis.ApexBulk` |
29
+ | ApexExecute | `com.provar.plugins.forcedotcom.core.testapis.ApexExecute` |
30
+ | ApexConvertLead | `com.provar.plugins.forcedotcom.core.testapis.ApexConvertLead` |
31
+ | ApexExtractLayout | `com.provar.plugins.forcedotcom.core.testapis.ApexExtractLayout` |
32
+ | ApexAssertLayout | `com.provar.plugins.forcedotcom.core.testapis.ApexAssertLayout` |
33
+ | ApexApproveWorkItem | `com.provar.plugins.forcedotcom.core.testapis.ApexApproveWorkItem` |
34
+ | ApexSubmitForApproval | `com.provar.plugins.forcedotcom.core.testapis.ApexSubmitForApproval` |
35
+ | ApexLogForCleanup | `com.provar.plugins.forcedotcom.core.testapis.ApexLogForCleanup` |
36
+ | **UI Steps** | |
37
+ | UiWithScreen | `com.provar.plugins.forcedotcom.core.ui.UiWithScreen` |
38
+ | UiDoAction | `com.provar.plugins.forcedotcom.core.ui.UiDoAction` |
39
+ | UiAssert | `com.provar.plugins.forcedotcom.core.ui.UiAssert` |
40
+ | UiRead | `com.provar.plugins.forcedotcom.core.ui.UiRead` |
41
+ | UiFill | `com.provar.plugins.forcedotcom.core.ui.UiFill` |
42
+ | UiWithRow | `com.provar.plugins.forcedotcom.core.ui.UiWithRow` |
43
+ | UiHandleAlert | `com.provar.plugins.forcedotcom.core.ui.UiHandleAlert` |
44
+ | UiNavigate | `com.provar.plugins.forcedotcom.core.ui.UiNavigate` |
45
+ | **Control Flow** | |
46
+ | SetValues | `com.provar.plugins.bundled.apis.control.SetValues` |
47
+ | StepGroup | `com.provar.plugins.bundled.apis.control.StepGroup` |
48
+ | If | `com.provar.plugins.bundled.apis.If` |
49
+ | ForEach | `com.provar.plugins.bundled.apis.control.ForEach` |
50
+ | DoWhile | `com.provar.plugins.bundled.apis.control.DoWhile` |
51
+ | WaitFor | `com.provar.plugins.bundled.apis.control.WaitFor` |
52
+ | TryCatchFinally | `com.provar.plugins.bundled.apis.control.TryCatchFinally` |
53
+ | Switch | `com.provar.plugins.bundled.apis.Switch` |
54
+ | Sleep | `com.provar.plugins.bundled.apis.control.Sleep` |
55
+ | Fail | `com.provar.plugins.bundled.apis.control.Fail` |
56
+ | CallTest | `com.provar.plugins.bundled.apis.control.CallTest` |
57
+ | **Assertions** | |
58
+ | AssertValues | `com.provar.plugins.bundled.apis.AssertValues` |
59
+ | **BDD** | |
60
+ | Given | `com.provar.plugins.bundled.apis.bdd.Given` |
61
+ | When | `com.provar.plugins.bundled.apis.bdd.When` |
62
+ | Then | `com.provar.plugins.bundled.apis.bdd.Then` |
63
+ | And | `com.provar.plugins.bundled.apis.bdd.And` |
64
+ | But | `com.provar.plugins.bundled.apis.bdd.But` |
65
+ | **Design** | |
66
+ | ActualResult | `com.provar.plugins.bundled.apis.control.ActualResult` |
67
+ | DesignStep | `com.provar.plugins.bundled.apis.control.DesignStep` |
68
+ | **Database** | |
69
+ | DbConnect | `com.provar.plugins.bundled.apis.db.DbConnect` |
70
+ | DbRead | `com.provar.plugins.bundled.apis.db.DbRead` |
71
+ | DbInsert | `com.provar.plugins.bundled.apis.db.DbInsert` |
72
+ | DbUpdate | `com.provar.plugins.bundled.apis.db.DbUpdate` |
73
+ | DbDelete | `com.provar.plugins.bundled.apis.db.DbDelete` |
74
+ | SqlQuery | `com.provar.plugins.bundled.apis.db.SqlQuery` |
75
+ | **Web Service** | |
76
+ | WebConnect | `com.provar.plugins.bundled.apis.restservice.WebConnect` |
77
+ | RestRequest | `com.provar.plugins.bundled.apis.restservice.RestRequest` |
78
+ | SoapRequest | `com.provar.plugins.bundled.apis.restservice.SoapRequest` |
79
+ | **Messaging** | |
80
+ | PublishMessage | `com.provar.plugins.bundled.apis.messaging.PublishMessage` |
81
+ | Subscribe | `com.provar.plugins.bundled.apis.messaging.Subscribe` |
82
+ | ReceiveMessage | `com.provar.plugins.bundled.apis.messaging.ReceiveMessage` |
83
+ | SendMessage | `com.provar.plugins.bundled.apis.messaging.SendMessage` |
84
+ | **Utility** | |
85
+ | ListCompare | `com.provar.plugins.bundled.apis.list.ListCompare` |
86
+ | Match | `com.provar.plugins.bundled.apis.string.Match` |
87
+ | Read | `com.provar.plugins.bundled.apis.io.Read` |
88
+ | Write | `com.provar.plugins.bundled.apis.io.Write` |
89
+ | Split | `com.provar.plugins.bundled.apis.string.Split` |
90
+ | Replace | `com.provar.plugins.bundled.apis.string.Replace` |
91
+ | **ProvarAI / Labs** | |
92
+ | GenerateTestData | `com.provar.plugins.forcedotcom.core.testapis.generate.GenerateTestData` |
93
+ | GenerateTestCase | `com.provar.plugins.forcedotcom.core.testapis.GenerateTestCase` |
94
+ | PageObjectCleaner | `com.provar.plugins.bundled.apis.provarlabs.PageObjectCleaner` |
88
95
 
89
96
  ---
90
97
 
@@ -200,7 +207,7 @@ Opens a browser-only UI session. Use this when you have a separate ApexConnect f
200
207
 
201
208
  ## UI Steps
202
209
 
203
- UI steps must always be nested inside a `UiWithScreen` block. Never place `UiDoAction` or `UiAssert` directly in the top-level `<steps>` list.
210
+ UI steps must always be nested inside a `UiWithScreen` block. Never place any of the 7 UI action types (`UiDoAction`, `UiAssert`, `UiRead`, `UiFill`, `UiNavigate`, `UiWithRow`, `UiHandleAlert`) directly in the top-level `<steps>` list — they must descend from a `UiWithScreen` or `UiWithRow` ancestor through a `<clause name="substeps">` path. Validator rule **UI-NEST-STRUCT-001** fires once per offending step.
204
211
 
205
212
  ### UiWithScreen
206
213
 
@@ -566,7 +573,73 @@ Verifies field values or element state on the current screen. Must always includ
566
573
  </apiCall>
567
574
  ```
568
575
 
569
- **Valid `comparisonType` values:** `EqualTo` | `NotEqualTo` | `Contains` | `NotContains` | `StartsWith` | `EndsWith` | `None`
576
+ **Valid `comparisonType` values (UI Assert):** `EqualTo` | `Contains` | `StartsWith` | `EndsWith` | `Matches` | `None`
577
+
578
+ `comparisonType` is a single Provar enum (`com.provar.core.model.base.java.ComparisonType`), but **each step type accepts only a subset of it**. A value used outside its step's subset is _load-blocking_: the whole test case fails to load with `IllegalArgumentException: No enum constant …ComparisonType.<value>`. The set above is the **UI Assert** subset (`uiAttributeAssertion`); it is strictly smaller than the AssertValues subset. In particular `NotEqualTo`, `NotContains`, `NotStartsWith`, `NotEndsWith`, and the relational/presence operators are **valid in AssertValues but not in a UI Assert** — to negate a UI comparison, invert the assertion logic instead. The UI dropdown labels map as: Equals → `EqualTo`, Contains → `Contains`, Starts With → `StartsWith`, Ends With → `EndsWith`, Matches → `Matches`; the no-assert/read-only choices (Ignore / Read) map to the single enum value `None`. For the full AssertValues subset see [AssertValues](#assertvalues).
579
+
580
+ ### UiRead
581
+
582
+ Reads the current value of a field or element on the screen and binds it to a result variable so subsequent steps can reference it. Useful for capturing IDs from the URL bar, the value of a calculated field after Save, or any visible text whose value depends on prior screen state.
583
+
584
+ > The `locator` argument must use `class="uiLocator"` (validator rule **UI-LOCATOR-001**). In `provar_testcase_generate` the `locator` attribute is converted automatically.
585
+
586
+ ```xml
587
+ <apiCall apiId="com.provar.plugins.forcedotcom.core.ui.UiRead"
588
+ name="UiRead" testItemId="9"
589
+ title="Read the Account Id">
590
+ <arguments>
591
+ <argument id="locator">
592
+ <value class="uiLocator" uri="sf:ui:locator?name=Id&amp;binding=sf%3Aui%3Abinding%3Aobject%3Fobject%3DAccount%26field%3DId"/>
593
+ </argument>
594
+ <argument id="resultName">
595
+ <value class="value" valueClass="string">AccountId</value>
596
+ </argument>
597
+ <argument id="resultScope">
598
+ <value class="value" valueClass="string">Test</value>
599
+ </argument>
600
+ </arguments>
601
+ </apiCall>
602
+ ```
603
+
604
+ **Locator URI format:** `sf:ui:locator?name=FIELD_NAME&binding=...` — the URL-encoded `binding` parameter is required for Salesforce field references.
605
+
606
+ ### UiFill
607
+
608
+ Fills multiple fields on a form in a single step using a list of field-value pairs. Equivalent to a sequence of `UiDoAction` (`set`) calls but more compact when populating many fields at once.
609
+
610
+ > The `locator` argument must use `class="uiLocator"` (validator rule **UI-LOCATOR-001**). In `provar_testcase_generate` the `locator` attribute is converted automatically.
611
+ >
612
+ > **Best practice (rule UI-FILL-VERIFY-001):** follow each `UiFill` with a `UiAssert` to verify the fields actually accepted the values.
613
+
614
+ ```xml
615
+ <apiCall apiId="com.provar.plugins.forcedotcom.core.ui.UiFill"
616
+ name="UiFill" testItemId="11"
617
+ title="Fill required Lead fields">
618
+ <arguments>
619
+ <argument id="locator">
620
+ <value class="uiLocator" uri="sf:ui:locator?name=LeadForm"/>
621
+ </argument>
622
+ <argument id="fieldValues">
623
+ <value class="valueList" mutable="Mutable">
624
+ <namedValues>
625
+ <namedValue name="LastName">
626
+ <value class="value" valueClass="string">Provar_TestLead</value>
627
+ </namedValue>
628
+ <namedValue name="Company">
629
+ <value class="value" valueClass="string">Provar Test Company</value>
630
+ </namedValue>
631
+ </namedValues>
632
+ </value>
633
+ </argument>
634
+ <argument id="captureBefore">
635
+ <value class="value" valueClass="string">false</value>
636
+ </argument>
637
+ <argument id="captureAfter">
638
+ <value class="value" valueClass="string">false</value>
639
+ </argument>
640
+ </arguments>
641
+ </apiCall>
642
+ ```
570
643
 
571
644
  ### UiWithRow
572
645
 
@@ -822,6 +895,113 @@ Runs a SOQL query and stores results as a list variable. Always include `Id` and
822
895
 
823
896
  ---
824
897
 
898
+ ## Microsoft Dynamics & Power Platform Steps (Provar 3.0.7+)
899
+
900
+ Four `NitroXConnect:ms-*` connection-step variants ship in Provar 3.0.7 for the Microsoft Dynamics 365 and Microsoft Power Platform product family. All four share a common apiId base (`com.provar.plugins.forcedotcom.core.ui.NitroXConnect`) and differ only in the suffix after the colon.
901
+
902
+ | Shorthand | Fully-qualified apiId | Product |
903
+ | -------------------- | ------------------------------- | ------------------------ |
904
+ | MSDynamics365Connect | `…NitroXConnect:ms-dynamics365` | Dynamics 365 (CRM/ERP) |
905
+ | MSDataverseConnect | `…NitroXConnect:ms-dataverse` | Dataverse (data backend) |
906
+ | MSPowerAppConnect | `…NitroXConnect:ms-powerapp` | Power Apps |
907
+ | MSPowerPageConnect | `…NitroXConnect:ms-powerpage` | Power Pages |
908
+
909
+ > **First-class generation:** all four shorthand names auto-expand via `provar_testcase_generate` to the fully-qualified runtime ID. Validation (`API-UNKNOWN-001`) recognises every variant.
910
+
911
+ ### Shared arguments (all four variants)
912
+
913
+ | Argument | Required | Notes |
914
+ | --------------------- | -------- | ------------------------------------------------- |
915
+ | `connectionName` | yes | Reference to a UI connection configured in Provar |
916
+ | `resultName` | yes | Identifier for the connection result variable |
917
+ | `resultScope` | yes | `Test` / `Global` / `Folder` |
918
+ | `reuseConnectionName` | no | Reuse an existing browser session |
919
+ | `privateBrowsingMode` | no | Enable private/incognito mode |
920
+ | `webBrowser` | no | Override default browser |
921
+
922
+ ### Variant-specific arguments
923
+
924
+ | Variant | Variant-specific args |
925
+ | ---------------- | ------------------------------ |
926
+ | `ms-dynamics365` | `appName` |
927
+ | `ms-dataverse` | _(none)_ |
928
+ | `ms-powerapp` | `powerAppName` |
929
+ | `ms-powerpage` | `environment`, `powerPageName` |
930
+
931
+ ### Validation rules
932
+
933
+ - **`UI-NITROX-CONNECT-ARGS-001`** (critical) — rejects ApexConnect-only args (`autoCleanup`, `lightningMode`, `alreadyOpenBehaviour`, `closeAllPrimaryTabs`, `enableObjectIdLogging`, `quickUiLogin`, `uiApplicationName`, `cleanupConnectionName`) and rejects cross-variant args (e.g. `powerAppName` on `:ms-dynamics365`).
934
+ - **`UI-NITROX-VARIANT-ARG-001`** (minor) — flags missing or empty variant-specific args **unless** they are declared as runtime-bound parameters under `<generatedParameters>` (the data-driven test pattern, see below).
935
+
936
+ ### Data-driven pattern (runtime-bound parameters)
937
+
938
+ When a variant-specific arg is left empty intentionally — because the value is supplied at runtime by a test plan or data table — declare it as a parameter in a sibling `<generatedParameters>` block. `UI-NITROX-VARIANT-ARG-001` recognises this pattern and stays silent.
939
+
940
+ ```xml
941
+ <apiCall apiId="…NitroXConnect:ms-powerpage" name="NitroXConnect" testItemId="4"
942
+ title="MS Power Page Connect">
943
+ <arguments>
944
+ <argument id="connectionName"><value class="value" valueClass="string">UiConnection</value></argument>
945
+ <argument id="resultName"><value class="value" valueClass="string">MSPowerPageConnection</value></argument>
946
+ <argument id="resultScope"><value class="value" valueClass="string">Test</value></argument>
947
+ <argument id="environment"/>
948
+ <argument id="powerPageName"/>
949
+ </arguments>
950
+ <generatedParameters>
951
+ <apiParam group="ui" name="environment" title="Environment">
952
+ <type><textType/></type>
953
+ </apiParam>
954
+ <apiParam group="ui" name="powerPageName" title="Power Page Name">
955
+ <type><textType/></type>
956
+ </apiParam>
957
+ </generatedParameters>
958
+ </apiCall>
959
+ ```
960
+
961
+ ### Example: MSDynamics365Connect (literal args)
962
+
963
+ ```xml
964
+ <apiCall apiId="com.provar.plugins.forcedotcom.core.ui.NitroXConnect:ms-dynamics365"
965
+ name="NitroXConnect" testItemId="1" title="MS Dynamics 365 Connect: (UiConnection)">
966
+ <arguments>
967
+ <argument id="connectionName"><value class="value" valueClass="string">UiConnection</value></argument>
968
+ <argument id="resultName"><value class="value" valueClass="string">MSDynamics365Connection</value></argument>
969
+ <argument id="resultScope"><value class="value" valueClass="string">Test</value></argument>
970
+ <argument id="appName"><value class="value" valueClass="string">Sales Hub</value></argument>
971
+ </arguments>
972
+ </apiCall>
973
+ ```
974
+
975
+ ### Example: MSDataverseConnect (no variant args)
976
+
977
+ ```xml
978
+ <apiCall apiId="com.provar.plugins.forcedotcom.core.ui.NitroXConnect:ms-dataverse"
979
+ name="NitroXConnect" testItemId="2" title="MS Dataverse Connect: (UiConnection)">
980
+ <arguments>
981
+ <argument id="connectionName"><value class="value" valueClass="string">UiConnection</value></argument>
982
+ <argument id="resultName"><value class="value" valueClass="string">MSDataverseConnection</value></argument>
983
+ <argument id="resultScope"><value class="value" valueClass="string">Test</value></argument>
984
+ </arguments>
985
+ <generatedParameters/>
986
+ </apiCall>
987
+ ```
988
+
989
+ ### Example: MSPowerAppConnect
990
+
991
+ ```xml
992
+ <apiCall apiId="com.provar.plugins.forcedotcom.core.ui.NitroXConnect:ms-powerapp"
993
+ name="NitroXConnect" testItemId="3" title="MS Power App Connect: (UiConnection)">
994
+ <arguments>
995
+ <argument id="connectionName"><value class="value" valueClass="string">UiConnection</value></argument>
996
+ <argument id="resultName"><value class="value" valueClass="string">MSPowerAppConnection</value></argument>
997
+ <argument id="resultScope"><value class="value" valueClass="string">Test</value></argument>
998
+ <argument id="powerAppName"><value class="value" valueClass="string">MyCanvasApp</value></argument>
999
+ </arguments>
1000
+ </apiCall>
1001
+ ```
1002
+
1003
+ ---
1004
+
825
1005
  ## Control Flow
826
1006
 
827
1007
  ### SetValues
@@ -1078,6 +1258,16 @@ Variable-to-variable or variable-to-literal comparison. For UI field assertions
1078
1258
  </apiCall>
1079
1259
  ```
1080
1260
 
1261
+ **Valid `comparisonType` values (AssertValues):** `EqualTo` | `NotEqualTo` | `GreaterThan` | `GreaterThanOrEqualTo` | `LessThan` | `LessThanOrEqualTo` | `IsPresent` | `IsEmpty` | `Matches` | `NotMatches` | `Contains` | `NotContains` | `StartsWith` | `NotStartsWith` | `EndsWith` | `NotEndsWith`
1262
+
1263
+ This is the **AssertValues** subset of `com.provar.core.model.base.java.ComparisonType` (`assertValuesComparison`) — wider than the [UI Assert](#uiassert) subset. The negation and relational operators (`NotEqualTo`, `NotContains`, `NotStartsWith`, `NotEndsWith`, `NotMatches`, `GreaterThan`, `GreaterThanOrEqualTo`, `LessThan`, `LessThanOrEqualTo`, `IsPresent`, `IsEmpty`) are valid here but **not** on a UI Assert step. Using a value outside this subset is load-blocking (`IllegalArgumentException: No enum constant …ComparisonType.<value>`).
1264
+
1265
+ **Comparison semantics and field-type notes:**
1266
+
1267
+ - **Direction of `Contains`:** the comparison reads as `expectedValue` _contains_ `actualValue` — i.e. `actualValue` is the substring searched for inside `expectedValue`. Order the arguments accordingly.
1268
+ - **Encrypted fields:** a SOQL read of an encrypted field returns `null`, not the cleartext. Assert with `IsEmpty` (or compare against `null`) rather than the expected plaintext; an `EqualTo` against the real value will always fail.
1269
+ - **Rich-text / long-textarea fields:** values come back wrapped in HTML block markup (e.g. `<p>…</p>`), so an exact `EqualTo` against the raw text fails. Use `Contains` (with the inner text as `actualValue`) to match the meaningful content.
1270
+
1081
1271
  ---
1082
1272
 
1083
1273
  ## BDD Steps