@provartesting/provardx-cli 1.5.3 → 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 (47) 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 +13 -1
  5. package/lib/mcp/docs/VALIDATION_RULE_REGISTRY.md +225 -0
  6. package/lib/mcp/rules/comparisonTypeSets.d.ts +21 -0
  7. package/lib/mcp/rules/comparisonTypeSets.js +45 -0
  8. package/lib/mcp/rules/comparisonTypeSets.js.map +1 -0
  9. package/lib/mcp/rules/provar_best_practices_rules.json +119 -8
  10. package/lib/mcp/rules/provar_layer1_rules.json +151 -0
  11. package/lib/mcp/rules/provar_test_step_schema.json +3005 -0
  12. package/lib/mcp/server.d.ts +15 -0
  13. package/lib/mcp/server.js +64 -1
  14. package/lib/mcp/server.js.map +1 -1
  15. package/lib/mcp/tools/automationTools.js +38 -1
  16. package/lib/mcp/tools/automationTools.js.map +1 -1
  17. package/lib/mcp/tools/bestPracticesEngine.js +1068 -6
  18. package/lib/mcp/tools/bestPracticesEngine.js.map +1 -1
  19. package/lib/mcp/tools/hierarchyValidate.d.ts +2 -1
  20. package/lib/mcp/tools/hierarchyValidate.js +7 -1
  21. package/lib/mcp/tools/hierarchyValidate.js.map +1 -1
  22. package/lib/mcp/tools/projectValidateFromPath.js +1 -2
  23. package/lib/mcp/tools/projectValidateFromPath.js.map +1 -1
  24. package/lib/mcp/tools/sfSpawn.d.ts +23 -0
  25. package/lib/mcp/tools/sfSpawn.js +72 -1
  26. package/lib/mcp/tools/sfSpawn.js.map +1 -1
  27. package/lib/mcp/tools/testCaseGenerate.js +146 -12
  28. package/lib/mcp/tools/testCaseGenerate.js.map +1 -1
  29. package/lib/mcp/tools/testCaseValidate.d.ts +46 -0
  30. package/lib/mcp/tools/testCaseValidate.js +307 -41
  31. package/lib/mcp/tools/testCaseValidate.js.map +1 -1
  32. package/lib/mcp/tools/testPlanValidate.js +3 -2
  33. package/lib/mcp/tools/testPlanValidate.js.map +1 -1
  34. package/lib/mcp/tools/testSuiteValidate.js +3 -2
  35. package/lib/mcp/tools/testSuiteValidate.js.map +1 -1
  36. package/lib/mcp/utils/qualityThreshold.d.ts +8 -0
  37. package/lib/mcp/utils/qualityThreshold.js +42 -0
  38. package/lib/mcp/utils/qualityThreshold.js.map +1 -0
  39. package/lib/mcp/utils/testCaseId.d.ts +23 -0
  40. package/lib/mcp/utils/testCaseId.js +156 -0
  41. package/lib/mcp/utils/testCaseId.js.map +1 -0
  42. package/lib/services/projectValidation.js +2 -1
  43. package/lib/services/projectValidation.js.map +1 -1
  44. package/messages/sf.provar.automation.project.validate.md +1 -1
  45. package/messages/sf.provar.mcp.start.md +1 -0
  46. package/oclif.manifest.json +4 -4
  47. package/package.json +3 -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"}
@@ -573,7 +573,9 @@ Verifies field values or element state on the current screen. Must always includ
573
573
  </apiCall>
574
574
  ```
575
575
 
576
- **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).
577
579
 
578
580
  ### UiRead
579
581
 
@@ -1256,6 +1258,16 @@ Variable-to-variable or variable-to-literal comparison. For UI field assertions
1256
1258
  </apiCall>
1257
1259
  ```
1258
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
+
1259
1271
  ---
1260
1272
 
1261
1273
  ## BDD Steps
@@ -0,0 +1,225 @@
1
+ # Provar Validation Rule Registry
2
+
3
+ > **Generated** by `scripts/build-validation-rule-registry.cjs`. Do not edit by hand — re-run the script after changing a rule.
4
+
5
+ Provar test-case validation runs in two layers. This registry is the single canonical list of every rule across both.
6
+
7
+ - **Layer 1 — structural validity** (hand-coded in `testCaseValidate.ts`): emits `issues[]` with `ERROR`/`WARNING`. `is_valid = error_count === 0`.
8
+ - **Layer 2 — best practices** (`provar_best_practices_rules.json`, same engine/weights as the Quality Hub API): emits `best_practices_violations[]` with `critical`/`major`/`minor`/`info` and a weighted `quality_score`.
9
+
10
+ **Severity taxonomy:** `critical` = the test will not load/render in Provar; `major` = a runtime ERROR (loads, fails at execution); `minor` = warning; `info` = advisory.
11
+
12
+ **The validity bridge (PDX-509):** a `critical` best-practice violation is surfaced into `issues[]` as an `ERROR` and therefore gates `is_valid` — EXCEPT where a Layer-1 check already owns the concept (then it is suppressed to avoid double-reporting). `major`/`minor`/`info` affect `quality_score` (and the `needs_improvement` status) only. The `status` field is tri-state: `invalid` (a critical) / `needs_improvement` (loads but `quality_score < quality_threshold`) / `valid`.
13
+
14
+ **Counts:** Layer 1 — 23 rules (18 gating). Layer 2 — 178 rules (critical 64 / major 67 / minor 29 / info 18; 58 bridged to `is_valid`).
15
+
16
+ ## Layer 1 — Structural validity rules
17
+
18
+ | Rule ID | Severity | Gates is_valid? | Applies to | Checks |
19
+ | ------------------------- | -------- | --------------- | ---------- | ---------------------------------------------------------------------------------------------- |
20
+ | `TC_001` | ERROR | Yes | document | XML declaration present (<?xml …?> first line). |
21
+ | `TC_002` | ERROR | Yes | document | XML is well-formed (parses without error). |
22
+ | `TC_003` | ERROR | Yes | document | Root element is <testCase>. |
23
+ | `TC_010` | ERROR | Yes | testCase | testCase id, when present, is a non-negative integer (id is optional; guid is the identifier). |
24
+ | `TC_011` | ERROR | Yes | testCase | testCase has a guid attribute. |
25
+ | `TC_012` | ERROR | Yes | testCase | testCase guid is a valid UUID v4. |
26
+ | `TC_020` | ERROR | Yes | testCase | testCase has a <steps> element. |
27
+ | `TC_030` | ERROR | Yes | apiCall | Each apiCall has a guid attribute. |
28
+ | `TC_031` | ERROR | Yes | apiCall | Each apiCall guid is a valid UUID v4. |
29
+ | `TC_032` | ERROR | Yes | apiCall | Each apiCall has an apiId attribute. |
30
+ | `TC_033` | WARNING | No | apiCall | Each apiCall has a descriptive name attribute. |
31
+ | `TC_034` | ERROR | Yes | apiCall | Each apiCall has a testItemId attribute. |
32
+ | `TC_035` | ERROR | Yes | apiCall | apiCall testItemId is a whole number. |
33
+ | `DATA-001` | WARNING | No | testCase | <dataTable> only iterates under a test plan; flags direct testCase-mode execution. |
34
+ | `VAR-REF-001` | WARNING | No | argument | A whole-token {Var} stored as valueClass="string" (use class="variable"). |
35
+ | `VAR-REF-002` | WARNING | No | argument | {Var} tokens embedded in a plain string (use class="compound"). |
36
+ | `UI-TARGET-001` | ERROR | Yes | apiCall | UiWithScreen/UiWithRow target uses class="uiTarget". |
37
+ | `UI-LOCATOR-001` | ERROR | Yes | apiCall | UI action locator uses class="uiLocator". |
38
+ | `UI-INTERACTION-001` | ERROR | Yes | apiCall | UiDoAction interaction uses class="uiInteraction". |
39
+ | `UI-ASSERT-STRUCTURE-001` | ERROR | Yes | apiCall | UiAssert uses nested field/column/page assertion containers, not a flat argument. |
40
+ | `SETVALUES-STRUCTURE-001` | ERROR | Yes | apiCall | SetValues values argument uses class="valueList" with <namedValues>. |
41
+ | `ASSERT-001` | WARNING | No | apiCall | AssertValues namedValues format flagged for variable/Apex comparisons. |
42
+ | `COMPARISON-TYPE-001` | ERROR | Yes | apiCall | comparisonType is within the step-scoped enum subset (load-blocking otherwise). |
43
+
44
+ ## Layer 2 — Best-practice rules
45
+
46
+ | Rule ID | Category | Severity | Weight | Gates is_valid? | Checks |
47
+ | ---------------------------------------- | -------------------------- | -------- | ------ | --------------- | ---------------------------------------------------------------------------------------------------- |
48
+ | `APEX-ASSERT-LAYOUT-001` | ApexAPI | major | 5 | No | ApexAssertLayout must have object and expected file. |
49
+ | `APEX-CONNECTION-REF-001` | ApexAPI | major | 5 | No | Apex API steps must reference a valid connection. |
50
+ | `APEX-CREATE-FIELDS-001` | ApexAPI | major | 5 | No | ApexCreateObject with fields must populate at least one field. |
51
+ | `APEX-CREATE-METADATA-001` | ApexAPI | major | 5 | No | ApexCreateObject and ApexUpdateObject must include parameter metadata. |
52
+ | `APEX-CREATE-UPDATE-STRUCTURE-001` | ApexAPI | major | 5 | No | ApexUpdateObject/ApexCreateObject field arguments must be direct, not nested in uiObjectFieldValue. |
53
+ | `APEX-DELETE-ID-001` | ApexAPI | major | 5 | No | ApexDeleteObject must have valid record ID. |
54
+ | `APEX-EXTRACT-LAYOUT-001` | ApexAPI | major | 5 | No | ApexExtractLayout must have object, file type, and path. |
55
+ | `APEX-OBJECT-TYPE-001` | ApexAPI | major | 5 | No | Apex CRUD operations must have valid object types. |
56
+ | `APEX-PARAM-GEN-URI-001` | ApexAPI | minor | 2 | No | Apex CRUD operations should include parameterGeneratorUri. |
57
+ | `APEX-READ-ASSERTIONS-001` | ApexAPI | minor | 3 | No | ApexReadObject should use resultAssertions instead of separate AssertValues. |
58
+ | `APEX-READ-FIELDS-STRUCTURE-001` | ApexAPI | major | 5 | No | ApexReadObject must use generatedParameters for field references, not fields argument with textType. |
59
+ | `APEX-READ-ID-001` | ApexAPI | major | 5 | No | ApexReadObject must have valid record ID. |
60
+ | `APEX-UPDATE-FIELDS-001` | ApexAPI | major | 5 | No | ApexUpdateObject must specify fields to update. |
61
+ | `APEX-UPDATE-ID-001` | ApexAPI | major | 5 | No | ApexUpdateObject must have valid record ID. |
62
+ | `CONN-ARG-001` | ApexAPI | minor | 2 | No | Connection arguments must use correct naming convention. |
63
+ | `BUILD-PLAN-001` | BuildAndCI | major | 5 | No | Regression Test Plan exists for CI. |
64
+ | `APEX-AUTOCLEANUP-001` | ConnectionsAndEnvironments | minor | 2 | No | Prefer autoCleanup over manual ApexDeleteObject steps. |
65
+ | `CONN-APEX-001` | ConnectionsAndEnvironments | critical | 8 | Yes | Apex API calls reference valid connections. |
66
+ | `CONN-DB-001` | ConnectionsAndEnvironments | critical | 8 | Yes | Database operations reference valid connections. |
67
+ | `CONN-DB-002` | ConnectionsAndEnvironments | major | 5 | No | DbConnect resultName must match dbConnectionName in DB operations. |
68
+ | `CONN-UI-001` | ConnectionsAndEnvironments | critical | 8 | Yes | UI operations reference valid connections. |
69
+ | `DB-CONNECT-001` | ConnectionsAndEnvironments | critical | 8 | Yes | DbConnect has connectionName. |
70
+ | `DB-CONNECT-002` | ConnectionsAndEnvironments | critical | 8 | Yes | DbConnect has resultName. |
71
+ | `ENV-CONN-001` | ConnectionsAndEnvironments | major | 5 | No | Admin connection supports Login-As. |
72
+ | `ENV-CONN-002` | ConnectionsAndEnvironments | minor | 2 | No | Connection names should not contain environment specifiers. |
73
+ | `REST-CONN-001` | ConnectionsAndEnvironments | critical | 8 | Yes | WebConnect has connectionName. |
74
+ | `REST-CONN-002` | ConnectionsAndEnvironments | critical | 8 | Yes | WebConnect has resultName. |
75
+ | `UI-CONN-LITERAL-001` | ConnectionsAndEnvironments | critical | 8 | Yes | uiConnectionName must be a literal string. |
76
+ | `UI-CONNECT-ARGS-001` | ConnectionsAndEnvironments | critical | 10 | Yes | UiConnect has invalid arguments (ApexConnect arguments used). |
77
+ | `UI-NITROX-CONNECT-ARGS-001` | ConnectionsAndEnvironments | critical | 10 | Yes | NitroX MS connect step has invalid arguments. |
78
+ | `UI-NITROX-VARIANT-ARG-001` | ConnectionsAndEnvironments | minor | 2 | No | NitroX MS connect step missing variant-specific argument. |
79
+ | `DDT-EXCEL-001` | DataDrivenTesting | major | 5 | No | Excel headers match field label or API name. |
80
+ | `DDT-NO-FUNC-001` | DataDrivenTesting | major | 5 | No | No Excel functions in data. |
81
+ | `DDT-VAR-001` | DataDrivenTesting | minor | 3 | No | No hardcoded values in steps. |
82
+ | `VAR-NAMING-001` | DataDrivenTesting | major | 5 | No | Variable names must use valid identifiers. |
83
+ | `VAR-USAGE-001` | DataDrivenTesting | minor | 2 | No | Variable references use correct syntax. |
84
+ | `UI-BINDING-ORDER-001` | LocatorPatterns | major | 5 | No | UI binding parameter order must have object= first. |
85
+ | `MAINT-FOLDER-001` | MaintenanceAndFolders | minor | 3 | No | Folder-level setup test per application segment. |
86
+ | `MAINT-VERSION-001` | MaintenanceAndFolders | info | 1 | No | Consistent Provar/OS/browser versions. |
87
+ | `APEX-RESULTNAME-001` | NamingConventions | minor | 2 | No | ApexConnect resultName is unique. |
88
+ | `CUSTOM-FIELD-001` | NamingConventions | major | 5 | No | Custom fields end with \_\_c. |
89
+ | `NC-FIELD-001` | NamingConventions | minor | 2 | No | Field names use camelCase. |
90
+ | `NC-FOLDER-001` | NamingConventions | major | 5 | No | Folder names are modular and title-cased. |
91
+ | `NC-PARAM-001` | NamingConventions | major | 5 | No | Parameters and variables use camelCase. |
92
+ | `NC-PO-001` | NamingConventions | major | 5 | No | Page Objects use PascalCase. |
93
+ | `NC-TESTCASE-001` | NamingConventions | minor | 2 | No | Test case names use consistent naming convention. |
94
+ | `SETVALUES-NAME-001` | NamingConventions | critical | 8 | Yes | SetValues namedValue elements have name attribute. |
95
+ | `CALLABLE-VISIBILITY-001` | ReusabilityAndCallables | critical | 8 | Yes | Called test cases are marked as Callable. |
96
+ | `REUSE-CALL-001` | ReusabilityAndCallables | minor | 2 | No | Callable tests reside in Callables folder. |
97
+ | `REUSE-CALL-002` | ReusabilityAndCallables | minor | 2 | No | Callable tests are parameterized. |
98
+ | `REUSE-CALL-003` | ReusabilityAndCallables | minor | 2 | No | Callable tests executable in isolation. |
99
+ | `ASSERT-STR-VAR-001` | StructureAndGrouping | major | 5 | No | AssertValues must not use string literal to reference a variable. |
100
+ | `BDD-AND-LIMIT-001` | StructureAndGrouping | info | 1 | No | Limit And/But chain length. |
101
+ | `BDD-GIVEN-FIRST-001` | StructureAndGrouping | info | 1 | No | BDD scenario should start with Given. |
102
+ | `BDD-ORDER-001` | StructureAndGrouping | info | 1 | No | BDD steps should follow logical order. |
103
+ | `CONTROL-FINALLY-001` | StructureAndGrouping | major | 5 | No | Finally block should be at end of test. |
104
+ | `RENDER-ARG-001` | StructureAndGrouping | critical | 10 | Yes | All arguments must have value elements. |
105
+ | `RENDER-BOOL-001` | StructureAndGrouping | critical | 10 | Yes | Boolean values must use lowercase. |
106
+ | `RENDER-CASE-001` | StructureAndGrouping | critical | 10 | Yes | valueClass attributes must use lowercase. |
107
+ | `RENDER-ROOT-001` | StructureAndGrouping | minor | 3 | No | Test case root element should not have unknown attributes. |
108
+ | `SETVALUES-FUNC-STR-001` | StructureAndGrouping | major | 5 | No | SetValues must not use string interpolation for function calls. |
109
+ | `SETVALUES-INVALID-ELEMENT-001` | StructureAndGrouping | critical | 10 | Yes | SetValues must not contain invalid child elements. |
110
+ | `SETVALUES-ZERO-IDX-001` | StructureAndGrouping | major | 5 | No | SetValues string expression must not use [0] index. |
111
+ | `STEP-NAMES-001` | StructureAndGrouping | minor | 2 | No | Custom step names for UI asserts and sets. |
112
+ | `STRUCT-GROUP-001` | StructureAndGrouping | minor | 2 | No | All steps are inside Group steps or BDD structure. |
113
+ | `STRUCT-SUMMARY-001` | StructureAndGrouping | info | 1 | No | Test case has top-level summary. |
114
+ | `UI-ASSERT-STRUCT-001` | StructureAndGrouping | critical | 8 | Yes | UiAssert steps must include all required arguments. |
115
+ | `UI-ASSERT-STRUCT-002` | StructureAndGrouping | critical | 10 | Yes | UiAssert steps must NOT contain generatedParameters. |
116
+ | `VALUE-CLASS-001` | StructureAndGrouping | critical | 10 | Yes | Value elements must use valid class attribute. |
117
+ | `AI-CONVERSATION-SESSION-001` | TestCaseDesign | critical | 8 | Yes | AIAgentConversation requires valid session. |
118
+ | `AI-IMAGE-CONFIDENCE-001` | TestCaseDesign | major | 5 | No | ImageValidator confidence should be 0.0-1.0. |
119
+ | `AI-SESSION-WEBCONNECT-001` | TestCaseDesign | critical | 8 | Yes | AIAgentSession requires WebConnect first. |
120
+ | `AI-UTTERANCE-COUNT-001` | TestCaseDesign | info | 1 | No | GenerateUtterance count should be reasonable. |
121
+ | `APEX-BULK-LIMIT-001` | TestCaseDesign | info | 1 | No | ApexBulk should be used for large data volumes. |
122
+ | `APEX-EXECUTE-SYNTAX-001` | TestCaseDesign | critical | 8 | Yes | ApexExecute code should be valid Apex syntax. |
123
+ | `APEX-REUSE-CONN-001` | TestCaseDesign | major | 5 | No | ApexConnect reuseConnectionName should be left blank. |
124
+ | `ASSERT-ACTUAL-001` | TestCaseDesign | critical | 8 | Yes | AssertValues has actualValue. |
125
+ | `ASSERT-API-001` | TestCaseDesign | critical | 8 | Yes | Must use AssertValues API, not deprecated Assert API. |
126
+ | `ASSERT-ARG-ORDER-001` | TestCaseDesign | info | 1 | No | AssertValues arguments must be in correct order. |
127
+ | `ASSERT-COMPARISON-001` | TestCaseDesign | critical | 8 | Yes | AssertValues has comparisonType. |
128
+ | `ASSERT-DATE-FORMAT-001` | TestCaseDesign | minor | 4 | No | Date/DateTime assertions should use proper format functions. |
129
+ | `ASSERT-EXPECTED-001` | TestCaseDesign | critical | 8 | Yes | AssertValues has expectedValue. |
130
+ | `ASSERT-VALUES-COMPARISON-001` | TestCaseDesign | major | 5 | No | AssertValues should have meaningful expected values. |
131
+ | `BDD-GIVEN-001` | TestCaseDesign | major | 5 | No | Given steps have description. |
132
+ | `BDD-THEN-001` | TestCaseDesign | major | 5 | No | Then steps have description. |
133
+ | `BDD-WHEN-001` | TestCaseDesign | major | 5 | No | When steps have description. |
134
+ | `CLEANUP-CONSISTENCY-001` | TestCaseDesign | major | 5 | No | Manual cleanup matches object creation. |
135
+ | `CLEANUP-ORDER-001` | TestCaseDesign | minor | 2 | No | Cleanup deletes objects in reverse order. |
136
+ | `CONTROL-FINALLY-001` | TestCaseDesign | major | 5 | No | Finally block must have description and be at end. |
137
+ | `CONTROL-FOREACH-001` | TestCaseDesign | major | 4 | No | ForEach loops have valid source collection. |
138
+ | `CONTROL-FOREACH-002` | TestCaseDesign | critical | 8 | Yes | ForEach loops have valueName to store current item. |
139
+ | `CONTROL-IF-001` | TestCaseDesign | critical | 8 | Yes | If statements have conditions. |
140
+ | `CONTROL-SLEEP-001` | TestCaseDesign | major | 5 | No | Sleep step duration and frequency issues. |
141
+ | `CONTROL-SLEEP-001` | TestCaseDesign | info | 1 | No | Sleep duration should be under 5 seconds. |
142
+ | `CONTROL-SLEEP-002` | TestCaseDesign | critical | 8 | Yes | Sleep steps have duration specified. |
143
+ | `CONTROL-SWITCH-001` | TestCaseDesign | critical | 8 | Yes | Switch statements have value expression. |
144
+ | `CONTROL-WAITFOR-001` | TestCaseDesign | critical | 8 | Yes | WaitFor steps have condition. |
145
+ | `CONTROL-WAITFOR-002` | TestCaseDesign | major | 5 | No | WaitFor steps have max iterations limit. |
146
+ | `CONTROL-WHILE-001` | TestCaseDesign | critical | 8 | Yes | While loops have exit conditions. |
147
+ | `CONTROL-WHILE-MAX-001` | TestCaseDesign | major | 5 | No | While loop must have termination condition. |
148
+ | `CREATE-RESULT-001` | TestCaseDesign | major | 5 | No | ApexCreateObject steps specify resultIdName. |
149
+ | `DATA-DB-WHERE-001` | TestCaseDesign | critical | 8 | Yes | DbDelete and DbUpdate should have WHERE clause. |
150
+ | `DATA-REST-BODY-001` | TestCaseDesign | major | 5 | No | POST/PUT/PATCH should have request body. |
151
+ | `DATA-REST-METHOD-001` | TestCaseDesign | critical | 8 | Yes | RestRequest method should be valid HTTP method. |
152
+ | `DATA-REST-STATUS-001` | TestCaseDesign | info | 1 | No | Validate REST response status. |
153
+ | `DATA-SOAP-XML-001` | TestCaseDesign | critical | 8 | Yes | SOAP request body should be well-formed XML. |
154
+ | `DATA-TYPE-BOOL-001` | TestCaseDesign | critical | 8 | Yes | Boolean values are 'true' or 'false'. |
155
+ | `DATA-TYPE-NUMBER-001` | TestCaseDesign | info | 0 | No | Numeric values are valid numbers. |
156
+ | `DESIGN-APIUI-001` | TestCaseDesign | minor | 3 | No | Prefer API for setup where possible. |
157
+ | `DESIGN-GROUP-001` | TestCaseDesign | minor | 2 | No | Use Group Steps or BDD structure for logical phases. |
158
+ | `FILE-READ-PATH-001` | TestCaseDesign | critical | 8 | Yes | Read dataUrl should be valid file path. |
159
+ | `FILE-WRITE-PATH-001` | TestCaseDesign | critical | 8 | Yes | Write dataUrl should be writable. |
160
+ | `LOG-LEVEL-001` | TestCaseDesign | info | 1 | No | Log messages use appropriate log levels. |
161
+ | `MESSAGING-SUBSCRIBE-BEFORE-RECEIVE-001` | TestCaseDesign | critical | 8 | Yes | Subscribe before ReceiveMessage. |
162
+ | `MESSAGING-TIMEOUT-001` | TestCaseDesign | info | 1 | No | ReceiveMessage timeout should be reasonable. |
163
+ | `PICKLIST-001` | TestCaseDesign | major | 7 | No | Picklist values should match Salesforce metadata. |
164
+ | `PO-FIELD-EXISTS-001` | TestCaseDesign | major | 5 | No | Page Object locator references non-existent field. |
165
+ | `REST-REQUEST-001` | TestCaseDesign | critical | 8 | Yes | RestRequest has connectionName. |
166
+ | `SETVALUES-STRUCTURE-001` | TestCaseDesign | critical | 8 | Yes | SetValues steps have namedValues container. |
167
+ | `SETVALUES-VALUE-001` | TestCaseDesign | critical | 8 | Yes | SetValues namedValue elements have value element. |
168
+ | `SF-CONVERT-LEAD-STATUS-001` | TestCaseDesign | critical | 8 | Yes | ConvertLead status must be valid. |
169
+ | `SF-LAYOUT-EXTRACT-BEFORE-ASSERT-001` | TestCaseDesign | minor | 2 | No | ExtractSalesforceLayout before AssertSalesforceLayout. |
170
+ | `SOQL-IN-LOOP-001` | TestCaseDesign | major | 5 | No | SOQL queries must not be inside loops. |
171
+ | `SOQL-QUERY-001` | TestCaseDesign | critical | 8 | Yes | ApexSoqlQuery has soqlQuery argument. |
172
+ | `SOQL-RESULT-001` | TestCaseDesign | critical | 8 | Yes | SOQL queries specify resultListName. |
173
+ | `SOQL-SELECT-ID-001` | TestCaseDesign | minor | 2 | No | SOQL queries include Id and Name. |
174
+ | `SOQL-STRUCTURE-001` | TestCaseDesign | critical | 8 | Yes | SOQL queries have SELECT and FROM clauses. |
175
+ | `SOQL-WHERE-001` | TestCaseDesign | major | 5 | No | SOQL queries include WHERE or LIMIT clause. |
176
+ | `SQL-QUERY-001` | TestCaseDesign | critical | 8 | Yes | SqlQuery has query argument. |
177
+ | `SQL-QUERY-002` | TestCaseDesign | critical | 8 | Yes | SqlQuery has dbConnectionName. |
178
+ | `STEP-DISABLED-001` | TestCaseDesign | minor | 2 | No | Disabled test steps should be removed. |
179
+ | `STEP-ITEMID-001` | TestCaseDesign | critical | 8 | No | testItemId values are whole numbers. _(Layer-1 owns this concept; not bridged)_ |
180
+ | `TEST-LENGTH-001` | TestCaseDesign | minor | 3 | No | Test case should not be excessively long. |
181
+ | `UI-ALERT-HANDLE-001` | TestCaseDesign | info | 1 | No | UiHandleAlert should capture alert text. |
182
+ | `UI-ASSERT-COMPOUND-001` | TestCaseDesign | major | 6 | No | UiAssert must use compound fields for component field assertions. |
183
+ | `UI-ASSERT-FIELDLOCATOR-001` | TestCaseDesign | major | 5 | No | UiAssert fieldLocator uses object+field binding. |
184
+ | `UI-ASSERT-FIELDLOCATOR-002` | TestCaseDesign | major | 5 | No | UiAssert fieldAssertion must not wrap fieldLocator in uiLocator. |
185
+ | `UI-ASSERT-FIELDLOCATOR-003` | TestCaseDesign | critical | 10 | Yes | UiAssert bare locator in Salesforce metadata context causes render failure. |
186
+ | `UI-ASSERT-TYPE-001` | TestCaseDesign | minor | 2 | No | UiAssert steps specify assertion type. |
187
+ | `UI-DOACTION-VALUE-001` | TestCaseDesign | critical | 8 | Yes | UiDoAction Set requires value argument. |
188
+ | `UI-FIELD-METADATA-001` | TestCaseDesign | major | 5 | No | UiDoAction/UiAssert fields should exist in Salesforce metadata. |
189
+ | `UI-FILL-VERIFY-001` | TestCaseDesign | info | 1 | No | Verify fields after UiFill. |
190
+ | `UI-LOCATOR-ACTION-001` | TestCaseDesign | major | 5 | No | UiDoAction locator URIs must use valid patterns. |
191
+ | `UI-LOCATOR-BINDING-001` | TestCaseDesign | major | 5 | No | Ui locator built-in actions use object binding. |
192
+ | `UI-LOCATOR-BUTTON-CASING-001` | TestCaseDesign | major | 5 | No | Standard Salesforce flow buttons must use correct locator pattern. |
193
+ | `UI-LOCATOR-RECORDTYPE-001` | TestCaseDesign | major | 5 | No | Record Type field locator must use name=RecordType not name=recordTypeId. |
194
+ | `UI-LOCATOR-SAVE-001` | TestCaseDesign | major | 5 | No | Save button locator must use correct pattern. |
195
+ | `UI-LOOKUP-ID-001` | TestCaseDesign | major | 6 | No | UiDoAction lookup fields should use Name values, not IDs. |
196
+ | `UI-NAVIGATE-PREFER-SCREEN-001` | TestCaseDesign | info | 1 | No | Prefer UiWithScreen over UiNavigate for Salesforce. |
197
+ | `UI-SCREEN-NAV-001` | TestCaseDesign | major | 5 | No | First UiWithScreen must use navigate=Always or IfNeccessary. |
198
+ | `UI-SCREEN-NAV-002` | TestCaseDesign | minor | 2 | No | First UiWithScreen should prefer navigate=Always over IfNeccessary. |
199
+ | `UI-SCREEN-OBJID-001` | TestCaseDesign | major | 5 | No | UiWithScreen with navigate=Always for Edit/View must have sfUiTargetObjectId. |
200
+ | `UI-SCREEN-TARGET-001` | TestCaseDesign | major | 5 | No | UiWithScreen target URIs must use valid patterns. |
201
+ | `UI-TARGET-ACTION-001` | TestCaseDesign | major | 5 | No | UiWithScreen target uses invalid action value. |
202
+ | `UI-WAIT-VALUECLASS-001` | TestCaseDesign | major | 5 | No | Wait arguments must use uiWait value class. |
203
+ | `UTIL-MATCH-REGEX-001` | TestCaseDesign | critical | 8 | Yes | Match regex pattern should be valid. |
204
+ | `UTIL-REPLACE-EMPTY-001` | TestCaseDesign | major | 5 | No | Replace searchString should not be empty. |
205
+ | `UTIL-SPLIT-DELIMITER-001` | TestCaseDesign | major | 5 | No | Split delimiter should not be empty. |
206
+ | `VALID-GUID-001` | TestCaseDesign | critical | 8 | No | Test case has valid identifier. _(Layer-1 owns this concept; not bridged)_ |
207
+ | `VALID-STEPS-001` | TestCaseDesign | critical | 8 | No | Test case has steps element. _(Layer-1 owns this concept; not bridged)_ |
208
+ | `VAR-PROPERTY-001` | TestCaseDesign | major | 6 | No | Variable property references must be valid. |
209
+ | `VAR-REFERENCE-001` | TestCaseDesign | major | 5 | No | Variables are defined before use. |
210
+ | `VAR-STRING-LITERAL-001` | TestCaseDesign | major | 5 | No | Variable reference stored as plain string. |
211
+ | `APEX-APIPARAM-HALLUCINATION-001` | XMLSchema | critical | 10 | Yes | Apex CRUD apiParam elements must be self-closing without summary/type children. |
212
+ | `APEX-CONNECT-ARGS-001` | XMLSchema | critical | 10 | Yes | ApexConnect - Only valid argument IDs allowed. |
213
+ | `APEX-CONNECT-CONNID-001` | XMLSchema | critical | 10 | Yes | ApexConnect connectionId must use valueClass='id'. |
214
+ | `API-UNKNOWN-001` | XMLSchema | critical | 10 | Yes | API identifier must be a valid Provar API. |
215
+ | `FUNCCALL-VALID-001` | XMLSchema | major | 6 | No | funcCall id must be a valid Provar function. |
216
+ | `RENDER-DATE-VALUECLASS-001` | XMLSchema | critical | 10 | Yes | valueClass='date' requires epoch timestamp, not date string. |
217
+ | `SCHEMA-EMPTY-001` | XMLSchema | minor | 2 | No | Test case should not be empty. |
218
+ | `SCHEMA-ID-001` | XMLSchema | critical | 10 | No | Test case must have valid identifier. _(Layer-1 owns this concept; not bridged)_ |
219
+ | `SCHEMA-LEGACY-001` | XMLSchema | info | 1 | No | Consider migrating from registryId to id or guid. |
220
+ | `SCHEMA-ROOT-001` | XMLSchema | critical | 10 | No | Test case root element must be testCase. _(Layer-1 owns this concept; not bridged)_ |
221
+ | `SCHEMA-STEPS-001` | XMLSchema | critical | 10 | No | Test case must have steps element. _(Layer-1 owns this concept; not bridged)_ |
222
+ | `SCHEMA-URI-001` | XMLSchema | critical | 10 | Yes | URI attributes must properly encode ampersands. |
223
+ | `SCHEMA-VALUE-001` | XMLSchema | critical | 10 | Yes | Value elements must not use text attribute. |
224
+ | `STRUCT-ATTR-001` | XMLSchema | info | 1 | No | Test case should have failureBehaviour attribute. |
225
+ | `UI-NEST-STRUCT-001` | XMLSchema | major | 7 | No | UI action steps must be nested inside a UiWithScreen substeps clause. |
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Canonical, step-scoped `comparisonType` subsets — the single source of truth
3
+ * shared by the docs (PROVAR_TEST_STEP_REFERENCE.md / mcp.md) and the local
4
+ * `comparisonType` enum validator (testCaseValidate.ts).
5
+ *
6
+ * `comparisonType` is a single Provar enum
7
+ * (`com.provar.core.model.base.java.ComparisonType`), but each step type accepts
8
+ * only a SUBSET. A value used outside the subset its step type allows is
9
+ * load-blocking: the whole test case fails to load at runtime with
10
+ * `IllegalArgumentException: No enum constant ...ComparisonType.<value>`.
11
+ *
12
+ * Both subsets are confirmed from Provar-Automation-authored testcases (created
13
+ * directly in the product). Do NOT hand-duplicate these lists elsewhere — import
14
+ * from here.
15
+ */
16
+ /** AssertValues (`assertValuesComparison`) — the 16-value subset. */
17
+ export declare const ASSERT_VALUES_COMPARISON_TYPES: readonly ["EqualTo", "NotEqualTo", "GreaterThan", "GreaterThanOrEqualTo", "LessThan", "LessThanOrEqualTo", "IsPresent", "IsEmpty", "Matches", "NotMatches", "Contains", "NotContains", "StartsWith", "NotStartsWith", "EndsWith", "NotEndsWith"];
18
+ /** UI Assert (`uiAttributeAssertion`) — the narrower 6-value subset. */
19
+ export declare const UI_ASSERT_COMPARISON_TYPES: readonly ["EqualTo", "Contains", "StartsWith", "EndsWith", "Matches", "None"];
20
+ export declare const ASSERT_VALUES_COMPARISON_TYPE_SET: ReadonlySet<string>;
21
+ export declare const UI_ASSERT_COMPARISON_TYPE_SET: ReadonlySet<string>;
@@ -0,0 +1,45 @@
1
+ /*
2
+ * Copyright (c) 2024 Provar Limited.
3
+ * All rights reserved.
4
+ * Licensed under the BSD 3-Clause license.
5
+ * For full license text, see LICENSE.md file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+ /**
8
+ * Canonical, step-scoped `comparisonType` subsets — the single source of truth
9
+ * shared by the docs (PROVAR_TEST_STEP_REFERENCE.md / mcp.md) and the local
10
+ * `comparisonType` enum validator (testCaseValidate.ts).
11
+ *
12
+ * `comparisonType` is a single Provar enum
13
+ * (`com.provar.core.model.base.java.ComparisonType`), but each step type accepts
14
+ * only a SUBSET. A value used outside the subset its step type allows is
15
+ * load-blocking: the whole test case fails to load at runtime with
16
+ * `IllegalArgumentException: No enum constant ...ComparisonType.<value>`.
17
+ *
18
+ * Both subsets are confirmed from Provar-Automation-authored testcases (created
19
+ * directly in the product). Do NOT hand-duplicate these lists elsewhere — import
20
+ * from here.
21
+ */
22
+ /** AssertValues (`assertValuesComparison`) — the 16-value subset. */
23
+ export const ASSERT_VALUES_COMPARISON_TYPES = [
24
+ 'EqualTo',
25
+ 'NotEqualTo',
26
+ 'GreaterThan',
27
+ 'GreaterThanOrEqualTo',
28
+ 'LessThan',
29
+ 'LessThanOrEqualTo',
30
+ 'IsPresent',
31
+ 'IsEmpty',
32
+ 'Matches',
33
+ 'NotMatches',
34
+ 'Contains',
35
+ 'NotContains',
36
+ 'StartsWith',
37
+ 'NotStartsWith',
38
+ 'EndsWith',
39
+ 'NotEndsWith',
40
+ ];
41
+ /** UI Assert (`uiAttributeAssertion`) — the narrower 6-value subset. */
42
+ export const UI_ASSERT_COMPARISON_TYPES = ['EqualTo', 'Contains', 'StartsWith', 'EndsWith', 'Matches', 'None'];
43
+ export const ASSERT_VALUES_COMPARISON_TYPE_SET = new Set(ASSERT_VALUES_COMPARISON_TYPES);
44
+ export const UI_ASSERT_COMPARISON_TYPE_SET = new Set(UI_ASSERT_COMPARISON_TYPES);
45
+ //# sourceMappingURL=comparisonTypeSets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comparisonTypeSets.js","sourceRoot":"","sources":["../../../src/mcp/rules/comparisonTypeSets.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;;;GAcG;AAEH,qEAAqE;AACrE,MAAM,CAAC,MAAM,8BAA8B,GAAG;IAC5C,SAAS;IACT,YAAY;IACZ,aAAa;IACb,sBAAsB;IACtB,UAAU;IACV,mBAAmB;IACnB,WAAW;IACX,SAAS;IACT,SAAS;IACT,YAAY;IACZ,UAAU;IACV,aAAa;IACb,YAAY;IACZ,eAAe;IACf,UAAU;IACV,aAAa;CACL,CAAC;AAEX,wEAAwE;AACxE,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,CAAU,CAAC;AAExH,MAAM,CAAC,MAAM,iCAAiC,GAAwB,IAAI,GAAG,CAAC,8BAA8B,CAAC,CAAC;AAE9G,MAAM,CAAC,MAAM,6BAA6B,GAAwB,IAAI,GAAG,CAAC,0BAA0B,CAAC,CAAC"}