@provartesting/provardx-cli 1.5.0-beta.1 → 1.5.0-beta.11
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 +137 -13
- package/lib/commands/provar/auth/clear.d.ts +7 -0
- package/lib/commands/provar/auth/clear.js +36 -0
- package/lib/commands/provar/auth/clear.js.map +1 -0
- package/lib/commands/provar/auth/login.d.ts +10 -0
- package/lib/commands/provar/auth/login.js +90 -0
- package/lib/commands/provar/auth/login.js.map +1 -0
- package/lib/commands/provar/auth/rotate.d.ts +7 -0
- package/lib/commands/provar/auth/rotate.js +42 -0
- package/lib/commands/provar/auth/rotate.js.map +1 -0
- package/lib/commands/provar/auth/status.d.ts +7 -0
- package/lib/commands/provar/auth/status.js +107 -0
- package/lib/commands/provar/auth/status.js.map +1 -0
- package/lib/mcp/docs/PROVAR_TEST_STEP_REFERENCE.md +1430 -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 +19 -0
- package/lib/mcp/prompts/index.js.map +1 -0
- package/lib/mcp/prompts/loopPrompts.d.ts +6 -0
- package/lib/mcp/prompts/loopPrompts.js +435 -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/rules/provar_best_practices_rules.json +256 -544
- package/lib/mcp/server.js +45 -1
- package/lib/mcp/server.js.map +1 -1
- package/lib/mcp/tools/antTools.d.ts +15 -0
- package/lib/mcp/tools/antTools.js +204 -50
- package/lib/mcp/tools/antTools.js.map +1 -1
- package/lib/mcp/tools/automationTools.d.ts +36 -3
- package/lib/mcp/tools/automationTools.js +335 -42
- package/lib/mcp/tools/automationTools.js.map +1 -1
- package/lib/mcp/tools/bestPracticesEngine.js +161 -23
- package/lib/mcp/tools/bestPracticesEngine.js.map +1 -1
- package/lib/mcp/tools/connectionTools.d.ts +4 -0
- package/lib/mcp/tools/connectionTools.js +168 -0
- package/lib/mcp/tools/connectionTools.js.map +1 -0
- package/lib/mcp/tools/nitroXTools.d.ts +22 -0
- package/lib/mcp/tools/nitroXTools.js +750 -0
- package/lib/mcp/tools/nitroXTools.js.map +1 -0
- package/lib/mcp/tools/pageObjectGenerate.js +103 -35
- package/lib/mcp/tools/pageObjectGenerate.js.map +1 -1
- package/lib/mcp/tools/propertiesTools.d.ts +2 -0
- package/lib/mcp/tools/propertiesTools.js +277 -39
- package/lib/mcp/tools/propertiesTools.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/mcp/tools/qualityHubTools.js +127 -19
- package/lib/mcp/tools/qualityHubTools.js.map +1 -1
- package/lib/mcp/tools/rcaTools.d.ts +3 -2
- package/lib/mcp/tools/rcaTools.js +145 -20
- package/lib/mcp/tools/rcaTools.js.map +1 -1
- package/lib/mcp/tools/testCaseGenerate.js +88 -59
- package/lib/mcp/tools/testCaseGenerate.js.map +1 -1
- package/lib/mcp/tools/testCaseStepTools.d.ts +4 -0
- package/lib/mcp/tools/testCaseStepTools.js +221 -0
- package/lib/mcp/tools/testCaseStepTools.js.map +1 -0
- package/lib/mcp/tools/testCaseValidate.d.ts +11 -0
- package/lib/mcp/tools/testCaseValidate.js +146 -19
- package/lib/mcp/tools/testCaseValidate.js.map +1 -1
- package/lib/services/auth/credentials.d.ts +21 -0
- package/lib/services/auth/credentials.js +75 -0
- package/lib/services/auth/credentials.js.map +1 -0
- package/lib/services/auth/loginFlow.d.ts +68 -0
- package/lib/services/auth/loginFlow.js +216 -0
- package/lib/services/auth/loginFlow.js.map +1 -0
- package/lib/services/qualityHub/client.d.ts +161 -0
- package/lib/services/qualityHub/client.js +226 -0
- package/lib/services/qualityHub/client.js.map +1 -0
- package/messages/sf.provar.auth.clear.md +16 -0
- package/messages/sf.provar.auth.login.md +31 -0
- package/messages/sf.provar.auth.rotate.md +23 -0
- package/messages/sf.provar.auth.status.md +16 -0
- package/oclif.manifest.json +214 -1
- package/package.json +8 -4
|
@@ -10,10 +10,10 @@ export interface LicenseValidationResult {
|
|
|
10
10
|
/**
|
|
11
11
|
* Validate the Provar license before starting the MCP server.
|
|
12
12
|
*
|
|
13
|
-
* Requires Provar Automation IDE to be installed with an activated
|
|
13
|
+
* Requires Provar Automation IDE to be installed with an activated license.
|
|
14
14
|
* We trust the IDE's own licenseStatus field — if it says "Activated" we
|
|
15
15
|
* accept it. The IDE is responsible for setting licenseStatus to "Expired"
|
|
16
|
-
* or "Invalid" when a
|
|
16
|
+
* or "Invalid" when a license lapses; we do not re-check timing ourselves.
|
|
17
17
|
*
|
|
18
18
|
* The result is cached so repeated starts within 2 hours skip the IDE file
|
|
19
19
|
* read entirely. The 48-hour grace window lets the MCP server keep running
|
|
@@ -22,7 +22,7 @@ export interface LicenseValidationResult {
|
|
|
22
22
|
*
|
|
23
23
|
* Validation flow:
|
|
24
24
|
* 1. MCP cache fresh (< 2h) → serve from cache, skip IDE read
|
|
25
|
-
* 2. Scan ~/Provar/.licenses/*.properties for an Activated
|
|
25
|
+
* 2. Scan ~/Provar/.licenses/*.properties for an Activated license
|
|
26
26
|
* 3. Found → write cache, accept (offlineGrace=false)
|
|
27
27
|
* 4. Not found but MCP cache within 48h grace → serve, offlineGrace=true
|
|
28
28
|
* 5. Not found, no usable cache → throw LICENSE_NOT_FOUND
|
|
@@ -16,10 +16,10 @@ const IDE_CACHE_KEY = '__ide_detection__';
|
|
|
16
16
|
/**
|
|
17
17
|
* Validate the Provar license before starting the MCP server.
|
|
18
18
|
*
|
|
19
|
-
* Requires Provar Automation IDE to be installed with an activated
|
|
19
|
+
* Requires Provar Automation IDE to be installed with an activated license.
|
|
20
20
|
* We trust the IDE's own licenseStatus field — if it says "Activated" we
|
|
21
21
|
* accept it. The IDE is responsible for setting licenseStatus to "Expired"
|
|
22
|
-
* or "Invalid" when a
|
|
22
|
+
* or "Invalid" when a license lapses; we do not re-check timing ourselves.
|
|
23
23
|
*
|
|
24
24
|
* The result is cached so repeated starts within 2 hours skip the IDE file
|
|
25
25
|
* read entirely. The 48-hour grace window lets the MCP server keep running
|
|
@@ -28,7 +28,7 @@ const IDE_CACHE_KEY = '__ide_detection__';
|
|
|
28
28
|
*
|
|
29
29
|
* Validation flow:
|
|
30
30
|
* 1. MCP cache fresh (< 2h) → serve from cache, skip IDE read
|
|
31
|
-
* 2. Scan ~/Provar/.licenses/*.properties for an Activated
|
|
31
|
+
* 2. Scan ~/Provar/.licenses/*.properties for an Activated license
|
|
32
32
|
* 3. Found → write cache, accept (offlineGrace=false)
|
|
33
33
|
* 4. Not found but MCP cache within 48h grace → serve, offlineGrace=true
|
|
34
34
|
* 5. Not found, no usable cache → throw LICENSE_NOT_FOUND
|
|
@@ -96,7 +96,7 @@ function validateViaIdeDetection() {
|
|
|
96
96
|
checkedAt: Date.now(),
|
|
97
97
|
};
|
|
98
98
|
writeCacheEntry(entry);
|
|
99
|
-
log('info', 'licenseValidator: IDE
|
|
99
|
+
log('info', 'licenseValidator: IDE license validated and cached', {
|
|
100
100
|
name: ideState.name,
|
|
101
101
|
licenseType: ideState.licenseType,
|
|
102
102
|
});
|
|
@@ -0,0 +1,19 @@
|
|
|
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
|
+
import { registerCrtMigrationPrompt, registerSeleniumMigrationPrompt, registerPlaywrightMigrationPrompt, } from './migrationPrompts.js';
|
|
8
|
+
import { registerLoopGeneratePrompt, registerLoopFixPrompt, registerLoopReviewPrompt, registerLoopCoveragePrompt, registerLoopDbPrompt, } from './loopPrompts.js';
|
|
9
|
+
export function registerAllPrompts(server) {
|
|
10
|
+
registerCrtMigrationPrompt(server);
|
|
11
|
+
registerSeleniumMigrationPrompt(server);
|
|
12
|
+
registerPlaywrightMigrationPrompt(server);
|
|
13
|
+
registerLoopGeneratePrompt(server);
|
|
14
|
+
registerLoopFixPrompt(server);
|
|
15
|
+
registerLoopReviewPrompt(server);
|
|
16
|
+
registerLoopCoveragePrompt(server);
|
|
17
|
+
registerLoopDbPrompt(server);
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/mcp/prompts/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACL,0BAA0B,EAC1B,+BAA+B,EAC/B,iCAAiC,GAClC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,EACrB,wBAAwB,EACxB,0BAA0B,EAC1B,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,UAAU,kBAAkB,CAAC,MAAiB;IAClD,0BAA0B,CAAC,MAAM,CAAC,CAAC;IACnC,+BAA+B,CAAC,MAAM,CAAC,CAAC;IACxC,iCAAiC,CAAC,MAAM,CAAC,CAAC;IAC1C,0BAA0B,CAAC,MAAM,CAAC,CAAC;IACnC,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,wBAAwB,CAAC,MAAM,CAAC,CAAC;IACjC,0BAA0B,CAAC,MAAM,CAAC,CAAC;IACnC,oBAAoB,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
export declare function registerLoopGeneratePrompt(server: McpServer): void;
|
|
3
|
+
export declare function registerLoopFixPrompt(server: McpServer): void;
|
|
4
|
+
export declare function registerLoopReviewPrompt(server: McpServer): void;
|
|
5
|
+
export declare function registerLoopCoveragePrompt(server: McpServer): void;
|
|
6
|
+
export declare function registerLoopDbPrompt(server: McpServer): void;
|
|
@@ -0,0 +1,435 @@
|
|
|
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
|
+
import { z } from 'zod';
|
|
8
|
+
// ── Shared helpers ────────────────────────────────────────────────────────────
|
|
9
|
+
function projectHint(projectPath) {
|
|
10
|
+
return projectPath
|
|
11
|
+
? `The Provar project root is: ${projectPath}`
|
|
12
|
+
: 'Ask the user for the Provar project root path if it is needed for file operations.';
|
|
13
|
+
}
|
|
14
|
+
// ── Prompt: provar.loop.generate ─────────────────────────────────────────────
|
|
15
|
+
export function registerLoopGeneratePrompt(server) {
|
|
16
|
+
server.prompt('provar.loop.generate', 'Generate a Provar XML test case from a user story or acceptance criteria. Retrieves corpus examples for grounding, generates the test, writes it to the project, then validates it with provar.testcase.validate.', {
|
|
17
|
+
story: z
|
|
18
|
+
.string()
|
|
19
|
+
.describe('The user story or acceptance criteria to test. Paste the full story text, or a numbered list of acceptance criteria. Include the Salesforce object name and the action being tested (e.g. "As a sales rep, I want to close an opportunity so that revenue is recorded").'),
|
|
20
|
+
projectPath: z
|
|
21
|
+
.string()
|
|
22
|
+
.optional()
|
|
23
|
+
.describe('Absolute path to the Provar project root. Used to locate the tests/ directory when writing the output file.'),
|
|
24
|
+
testName: z
|
|
25
|
+
.string()
|
|
26
|
+
.optional()
|
|
27
|
+
.describe('Optional name for the output test case file (without extension). Inferred from the story if omitted.'),
|
|
28
|
+
objectName: z
|
|
29
|
+
.string()
|
|
30
|
+
.optional()
|
|
31
|
+
.describe('Primary Salesforce object under test (e.g. "Opportunity", "Lead"). Helps scope the corpus query if present.'),
|
|
32
|
+
}, ({ story, projectPath, testName, objectName }) => ({
|
|
33
|
+
messages: [
|
|
34
|
+
{
|
|
35
|
+
role: 'user',
|
|
36
|
+
content: {
|
|
37
|
+
type: 'text',
|
|
38
|
+
text: `You are a Provar test automation expert. Generate a Provar XML test case from the user story below.
|
|
39
|
+
|
|
40
|
+
## Workflow
|
|
41
|
+
|
|
42
|
+
Follow these steps in order:
|
|
43
|
+
|
|
44
|
+
1. **Extract keywords** — identify the Salesforce object, the action (create/update/close/delete/view), and key
|
|
45
|
+
scenario details from the story. Use these as the query for step 2.
|
|
46
|
+
|
|
47
|
+
2. **Get corpus examples** — call \`provar.qualityhub.examples.retrieve\` with the keywords you extracted
|
|
48
|
+
(e.g. "close opportunity" or "create lead"). Use the returned XML examples as the sole reference for
|
|
49
|
+
Provar step structure and argument patterns. Do not invent XML structure from prior knowledge.
|
|
50
|
+
If the response has \`"count": 0\` with a \`"warning"\` field (API unavailable or not configured),
|
|
51
|
+
fall back: read the \`provar://docs/step-reference\` MCP resource for step types and attribute
|
|
52
|
+
formats, then continue.
|
|
53
|
+
|
|
54
|
+
3. **Map acceptance criteria to steps** — for each acceptance criterion, identify the corresponding Provar
|
|
55
|
+
step type: field fills → UiDoAction (set), button clicks → UiDoAction (action), field checks →
|
|
56
|
+
UiAssert, API data setup → ApexCreateObject, API verification → ApexReadObject.
|
|
57
|
+
|
|
58
|
+
4. **Generate the test case** — produce a valid Provar XML test case that tests the story's acceptance
|
|
59
|
+
criteria. Base the structure entirely on the corpus examples. Follow these rules:
|
|
60
|
+
- All UI steps must be nested inside UiWithScreen blocks
|
|
61
|
+
- The first UiWithScreen must use navigate="Always"
|
|
62
|
+
- UiAssert requires columnAssertions, pageAssertions, resultScope, captureAfter, beforeWait, autoRetry
|
|
63
|
+
- Use ApexConnect for the connection step (first step in the test)
|
|
64
|
+
- Wrap test body in TryCatchFinally if cleanup is needed (ApexDeleteObject in the finally clause)
|
|
65
|
+
|
|
66
|
+
5. **Write the file** — save the XML to the tests/ directory in the Provar project.
|
|
67
|
+
${projectHint(projectPath)}
|
|
68
|
+
${testName ? `Target file name: ${testName}.testcase` : 'Infer the file name from the story (snake_case).'}
|
|
69
|
+
|
|
70
|
+
6. **Validate** — call \`provar.testcase.validate\` on the saved file. If it reports errors, fix them
|
|
71
|
+
and re-validate until the file passes clean.
|
|
72
|
+
|
|
73
|
+
7. **Report** — summarise:
|
|
74
|
+
- Which acceptance criteria were covered and how
|
|
75
|
+
- Any criteria that could not be automated (add \`<!-- TODO: manual verification — <criterion> -->\` in the XML)
|
|
76
|
+
- Any validation warnings
|
|
77
|
+
|
|
78
|
+
## User Story
|
|
79
|
+
|
|
80
|
+
${story}
|
|
81
|
+
|
|
82
|
+
${objectName ? `Primary object: ${objectName}` : ''}
|
|
83
|
+
|
|
84
|
+
Begin with step 1: extract keywords, then call provar.qualityhub.examples.retrieve.`,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
}));
|
|
89
|
+
}
|
|
90
|
+
// ── Prompt: provar.loop.fix ───────────────────────────────────────────────────
|
|
91
|
+
export function registerLoopFixPrompt(server) {
|
|
92
|
+
server.prompt('provar.loop.fix', 'Fix a failing Provar test case using the output from provar.testrun.rca. Reads the current XML, retrieves corpus examples for the failing step type, applies targeted fixes, then re-validates.', {
|
|
93
|
+
testcasePath: z
|
|
94
|
+
.string()
|
|
95
|
+
.describe('Absolute path to the failing .testcase XML file. The file must be readable and within the --allowed-paths configured for this MCP server.'),
|
|
96
|
+
rcaOutput: z
|
|
97
|
+
.string()
|
|
98
|
+
.describe('The RCA report text from provar.testrun.rca, or a raw failure message from a test run. Include the full error text — step name, error type, and message. The more detail, the better the fix.'),
|
|
99
|
+
projectPath: z
|
|
100
|
+
.string()
|
|
101
|
+
.optional()
|
|
102
|
+
.describe('Absolute path to the Provar project root. Used to locate adjacent test files if needed.'),
|
|
103
|
+
}, ({ testcasePath, rcaOutput, projectPath }) => ({
|
|
104
|
+
messages: [
|
|
105
|
+
{
|
|
106
|
+
role: 'user',
|
|
107
|
+
content: {
|
|
108
|
+
type: 'text',
|
|
109
|
+
text: `You are a Provar test automation expert. Fix the failing test case at the path below.
|
|
110
|
+
|
|
111
|
+
## Failing test case
|
|
112
|
+
|
|
113
|
+
Path: ${testcasePath}
|
|
114
|
+
|
|
115
|
+
## RCA output
|
|
116
|
+
|
|
117
|
+
\`\`\`
|
|
118
|
+
${rcaOutput}
|
|
119
|
+
\`\`\`
|
|
120
|
+
|
|
121
|
+
${projectPath ? `Provar project root: ${projectPath}` : ''}
|
|
122
|
+
|
|
123
|
+
## Workflow
|
|
124
|
+
|
|
125
|
+
Follow these steps in order:
|
|
126
|
+
|
|
127
|
+
1. **Read the failing test case** — read the XML file at the path above using your file reading tools.
|
|
128
|
+
|
|
129
|
+
2. **Parse the failure** — from the RCA output, identify:
|
|
130
|
+
- Which step is failing (step name, testItemId, or title)
|
|
131
|
+
- The failure category (e.g. element not found, assertion mismatch, connection error, XML structure error)
|
|
132
|
+
- The specific error message
|
|
133
|
+
|
|
134
|
+
3. **Get corpus examples** — call \`provar.qualityhub.examples.retrieve\` with keywords describing the
|
|
135
|
+
failing step's scenario (e.g. "close opportunity UiDoAction" or "assert field value UiAssert").
|
|
136
|
+
Use the returned examples to verify the correct structure for the failing step type.
|
|
137
|
+
If the response has \`"count": 0\` with a \`"warning"\` field, fall back: read the
|
|
138
|
+
\`provar://docs/step-reference\` MCP resource for the correct attribute schema for the failing
|
|
139
|
+
step type, then continue.
|
|
140
|
+
|
|
141
|
+
4. **Diagnose the root cause** — compare the failing step's XML against the corpus examples. Common issues:
|
|
142
|
+
- Wrong interaction URI (action vs set vs file)
|
|
143
|
+
- Missing required UiAssert arguments (columnAssertions, pageAssertions, resultScope, captureAfter, beforeWait, autoRetry)
|
|
144
|
+
- UiDoAction (set) missing the value argument
|
|
145
|
+
- UiWithScreen navigate="Dont" on the first screen
|
|
146
|
+
- navigate="Always" on Edit/View without sfUiTargetObjectId
|
|
147
|
+
- Incorrect locator URI format
|
|
148
|
+
- connectionId using valueClass="string" instead of valueClass="id"
|
|
149
|
+
|
|
150
|
+
5. **Apply the fix** — rewrite only the failing step(s). Preserve all other steps unchanged. Write the
|
|
151
|
+
updated XML back to the same file path.
|
|
152
|
+
|
|
153
|
+
6. **Validate** — call \`provar.testcase.validate\` on the updated file. If new errors appear, fix them
|
|
154
|
+
and re-validate until the file passes clean.
|
|
155
|
+
|
|
156
|
+
7. **Report** — summarise:
|
|
157
|
+
- The root cause of the failure
|
|
158
|
+
- Exactly what was changed (step name, argument changed, before/after values)
|
|
159
|
+
- Any remaining warnings from validation
|
|
160
|
+
|
|
161
|
+
Begin with step 1: read the file at: ${testcasePath}`,
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
],
|
|
165
|
+
}));
|
|
166
|
+
}
|
|
167
|
+
// ── Prompt: provar.loop.review ────────────────────────────────────────────────
|
|
168
|
+
export function registerLoopReviewPrompt(server) {
|
|
169
|
+
server.prompt('provar.loop.review', 'Review a Provar test case for quality before committing. Runs structural validation, checks against corpus best practices, and reports quality gaps: missing assertions, hardcoded data, missing cleanup, and unmapped steps.', {
|
|
170
|
+
testcasePath: z
|
|
171
|
+
.string()
|
|
172
|
+
.describe('Absolute path to the .testcase XML file to review. Must be within the --allowed-paths configured for this MCP server.'),
|
|
173
|
+
projectPath: z.string().optional().describe('Absolute path to the Provar project root.'),
|
|
174
|
+
}, ({ testcasePath, projectPath }) => ({
|
|
175
|
+
messages: [
|
|
176
|
+
{
|
|
177
|
+
role: 'user',
|
|
178
|
+
content: {
|
|
179
|
+
type: 'text',
|
|
180
|
+
text: `You are a Provar test automation expert. Review the test case at the path below for quality and completeness.
|
|
181
|
+
|
|
182
|
+
## Test case to review
|
|
183
|
+
|
|
184
|
+
Path: ${testcasePath}
|
|
185
|
+
${projectPath ? `Provar project root: ${projectPath}` : ''}
|
|
186
|
+
|
|
187
|
+
## Workflow
|
|
188
|
+
|
|
189
|
+
Follow these steps in order:
|
|
190
|
+
|
|
191
|
+
1. **Validate** — call \`provar.testcase.validate\` on the file. Note all errors and warnings. Do not stop
|
|
192
|
+
here even if the file is valid — continue the review.
|
|
193
|
+
|
|
194
|
+
2. **Read the file** — read the XML to understand the test structure: what object is being tested, what
|
|
195
|
+
actions are performed, and what is being asserted.
|
|
196
|
+
|
|
197
|
+
3. **Get corpus examples** — call \`provar.qualityhub.examples.retrieve\` with keywords describing the
|
|
198
|
+
test scenario (e.g. "create opportunity", "close opportunity"). Use the returned examples as a
|
|
199
|
+
quality baseline. If the response has \`"count": 0\` with a \`"warning"\` field, fall back: read
|
|
200
|
+
the \`provar://docs/step-reference\` MCP resource for step type schemas, then continue the review
|
|
201
|
+
using that as the quality baseline.
|
|
202
|
+
|
|
203
|
+
4. **Review for quality gaps** — check for each of the following, noting pass or fail:
|
|
204
|
+
|
|
205
|
+
**Coverage**
|
|
206
|
+
- [ ] Does the test assert the outcome of each action? (e.g. after clicking Save, is there a UiAssert?)
|
|
207
|
+
- [ ] Are all required fields verified, not just the ones that were set?
|
|
208
|
+
- [ ] Is there at least one UiAssert or ApexReadObject in the test?
|
|
209
|
+
|
|
210
|
+
**Data quality**
|
|
211
|
+
- [ ] Are test data values parameterised via SetValues rather than hardcoded in multiple steps?
|
|
212
|
+
- [ ] Are dynamic values (dates, IDs) referenced via variables rather than hardcoded strings?
|
|
213
|
+
|
|
214
|
+
**Cleanup**
|
|
215
|
+
- [ ] Is cleanup handled? Either autoCleanup=true on the connection, or ApexDeleteObject steps, or
|
|
216
|
+
a TryCatchFinally with cleanup in the finally clause?
|
|
217
|
+
|
|
218
|
+
**Structure**
|
|
219
|
+
- [ ] Does the first UiWithScreen use navigate="Always" or "IfNecessary"?
|
|
220
|
+
- [ ] Do Edit/View UiWithScreen steps with navigate="Always" include sfUiTargetObjectId?
|
|
221
|
+
- [ ] Are all UiDoAction and UiAssert steps inside UiWithScreen substeps clauses?
|
|
222
|
+
|
|
223
|
+
**Unmapped steps**
|
|
224
|
+
- [ ] Are there any \`<!-- TODO: -->\` comments indicating steps that couldn't be automated?
|
|
225
|
+
Flag these for manual review.
|
|
226
|
+
|
|
227
|
+
5. **Report** — produce a structured review with three sections:
|
|
228
|
+
|
|
229
|
+
### Passes
|
|
230
|
+
List what the test does well.
|
|
231
|
+
|
|
232
|
+
### Issues
|
|
233
|
+
For each gap found, state:
|
|
234
|
+
- What is missing or wrong
|
|
235
|
+
- Why it matters (e.g. "assertion missing after Save means the test won't catch a silent failure")
|
|
236
|
+
- A concrete fix (reference the corpus example if relevant)
|
|
237
|
+
|
|
238
|
+
### Suggested improvements
|
|
239
|
+
Any non-blocking suggestions (e.g. parameterising a hardcoded value that appears more than once).
|
|
240
|
+
|
|
241
|
+
Begin with step 1: call provar.testcase.validate on the file at: ${testcasePath}`,
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
],
|
|
245
|
+
}));
|
|
246
|
+
}
|
|
247
|
+
// ── Prompt: provar.loop.coverage ─────────────────────────────────────────────
|
|
248
|
+
export function registerLoopCoveragePrompt(server) {
|
|
249
|
+
server.prompt('provar.loop.coverage', 'Analyse test coverage for a Salesforce object. Scans the Provar project test files to identify which CRUD operations, field validations, and UI workflows are covered, then reports gaps with suggested test outlines.', {
|
|
250
|
+
objectName: z
|
|
251
|
+
.string()
|
|
252
|
+
.describe('The Salesforce API object name to analyse (e.g. "Opportunity", "Lead", "Contact", "Account"). Used to scan test cases and query the corpus for expected test patterns.'),
|
|
253
|
+
projectPath: z
|
|
254
|
+
.string()
|
|
255
|
+
.describe('Absolute path to the Provar project root. The tests/ subdirectory will be scanned for .testcase files.'),
|
|
256
|
+
targetOrg: z
|
|
257
|
+
.string()
|
|
258
|
+
.optional()
|
|
259
|
+
.describe('SF org alias or username. If provided, also queries provar.qualityhub.testcase.retrieve to include Quality Hub tests in the coverage analysis.'),
|
|
260
|
+
}, ({ objectName, projectPath, targetOrg }) => ({
|
|
261
|
+
messages: [
|
|
262
|
+
{
|
|
263
|
+
role: 'user',
|
|
264
|
+
content: {
|
|
265
|
+
type: 'text',
|
|
266
|
+
text: `You are a Provar test automation expert. Analyse test coverage for the Salesforce object "${objectName}".
|
|
267
|
+
|
|
268
|
+
## Provar project
|
|
269
|
+
|
|
270
|
+
Root: ${projectPath}
|
|
271
|
+
Object to analyse: ${objectName}
|
|
272
|
+
${targetOrg ? `Quality Hub org: ${targetOrg}` : ''}
|
|
273
|
+
|
|
274
|
+
## Workflow
|
|
275
|
+
|
|
276
|
+
Follow these steps in order:
|
|
277
|
+
|
|
278
|
+
1. **Scan local test files** — list all .testcase files under ${projectPath}/tests/. For each file that
|
|
279
|
+
references "${objectName}" (search for the string in the file content), read it and extract:
|
|
280
|
+
- The test scenario (from the file name or meta comment)
|
|
281
|
+
- Which operations are covered: API Create, API Read, API Update, API Delete, UI New, UI View,
|
|
282
|
+
UI Edit, UI Delete, UI assertions on fields
|
|
283
|
+
- Which fields are set or asserted
|
|
284
|
+
|
|
285
|
+
${targetOrg
|
|
286
|
+
? `2. **Query Quality Hub** — call \`provar.qualityhub.testcase.retrieve\` with target_org="${targetOrg}"
|
|
287
|
+
to retrieve test cases linked to the "${objectName}" object from Quality Hub. Add these to the
|
|
288
|
+
coverage inventory.
|
|
289
|
+
|
|
290
|
+
3. **Get corpus examples** — call \`provar.qualityhub.examples.retrieve\` with "${objectName.toLowerCase()}"
|
|
291
|
+
as the query to understand what test patterns exist in the corpus for this object.
|
|
292
|
+
If the response has \`"count": 0\` with a \`"warning"\` field, fall back: read the
|
|
293
|
+
\`provar://docs/step-reference\` MCP resource for step type schemas, then continue.`
|
|
294
|
+
: `2. **Get corpus examples** — call \`provar.qualityhub.examples.retrieve\` with "${objectName.toLowerCase()}"
|
|
295
|
+
as the query to understand what test patterns exist in the corpus for this object.
|
|
296
|
+
If the response has \`"count": 0\` with a \`"warning"\` field, fall back: read the
|
|
297
|
+
\`provar://docs/step-reference\` MCP resource for step type schemas, then continue.`}
|
|
298
|
+
|
|
299
|
+
${targetOrg ? '4' : '3'}. **Build the coverage matrix** — define the standard test scenarios for "${objectName}":
|
|
300
|
+
|
|
301
|
+
**API (Apex) operations**
|
|
302
|
+
- Create: ApexCreateObject with required fields
|
|
303
|
+
- Create: ApexCreateObject with optional/edge-case fields
|
|
304
|
+
- Read: ApexReadObject — verify created record
|
|
305
|
+
- Update: ApexUpdateObject — modify field values
|
|
306
|
+
- Delete: ApexDeleteObject — confirm record removed
|
|
307
|
+
- SOQL: ApexSoqlQuery — query by key fields
|
|
308
|
+
|
|
309
|
+
**UI operations**
|
|
310
|
+
- New: navigate to New screen, fill required fields, save → assert record created
|
|
311
|
+
- View: navigate to View screen → assert field values
|
|
312
|
+
- Edit: navigate to Edit screen, modify fields, save → assert changes persisted
|
|
313
|
+
- Delete: delete via UI → confirm record no longer visible
|
|
314
|
+
- Related lists: any relationships (e.g. Contacts on Account) that have UI tests
|
|
315
|
+
|
|
316
|
+
**Validation rules and required fields**
|
|
317
|
+
- Negative tests: attempt to save with missing required fields → assert error message shown
|
|
318
|
+
- Validation rule triggers: if known validation rules exist, is there a test for each?
|
|
319
|
+
|
|
320
|
+
${targetOrg ? '5' : '4'}. **Report coverage gaps** — produce a report with three sections:
|
|
321
|
+
|
|
322
|
+
### Covered
|
|
323
|
+
List each scenario that has at least one test, with the test file name.
|
|
324
|
+
|
|
325
|
+
### Gaps
|
|
326
|
+
For each missing scenario, state:
|
|
327
|
+
- What is not covered
|
|
328
|
+
- Why it matters (e.g. "No negative test for required fields means validation rule regressions won't be caught")
|
|
329
|
+
- A brief test outline (inputs, expected outcome, which step types to use)
|
|
330
|
+
|
|
331
|
+
### Suggested next tests
|
|
332
|
+
Rank the top 3-5 gaps by risk. For each, provide:
|
|
333
|
+
- A suggested test case name
|
|
334
|
+
- The key steps (using correct Provar step type names from the reference)
|
|
335
|
+
- Estimated effort (XS / S / M)
|
|
336
|
+
|
|
337
|
+
Begin with step 1: list the .testcase files in ${projectPath}/tests/ and search for "${objectName}".`,
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
],
|
|
341
|
+
}));
|
|
342
|
+
}
|
|
343
|
+
// ── Prompt: provar.loop.db ────────────────────────────────────────────────────
|
|
344
|
+
export function registerLoopDbPrompt(server) {
|
|
345
|
+
server.prompt('provar.loop.db', 'Generate a Provar XML test case that connects to an external database (SQL Server, Oracle, MySQL, etc.) and verifies query results. Distinct from Salesforce/SOQL flows — this targets DbConnect + SqlQuery steps. Retrieves corpus examples for grounding, enforces correct funcCall/variable-path patterns, generates the test, then validates.', {
|
|
346
|
+
story: z
|
|
347
|
+
.string()
|
|
348
|
+
.describe('Description of what the database test should verify. Include the database type (e.g. "SQL Server"), table name, query intent, and what values should be asserted (e.g. "Verify that the Users table contains an active user record with Status=Active after a Salesforce flow runs").'),
|
|
349
|
+
projectPath: z
|
|
350
|
+
.string()
|
|
351
|
+
.optional()
|
|
352
|
+
.describe('Absolute path to the Provar project root. Used to locate the tests/ directory.'),
|
|
353
|
+
testName: z
|
|
354
|
+
.string()
|
|
355
|
+
.optional()
|
|
356
|
+
.describe('Optional file name for the test case (without extension). Inferred from the story if omitted.'),
|
|
357
|
+
connectionName: z
|
|
358
|
+
.string()
|
|
359
|
+
.optional()
|
|
360
|
+
.describe('The Provar Connection Manager database connection name (DbConnect.connectionName). This identifies which connection entry to use. If omitted, the story should describe the connection to use.'),
|
|
361
|
+
}, ({ story, projectPath, testName, connectionName }) => ({
|
|
362
|
+
messages: [
|
|
363
|
+
{
|
|
364
|
+
role: 'user',
|
|
365
|
+
content: {
|
|
366
|
+
type: 'text',
|
|
367
|
+
text: `You are a Provar test automation expert. Generate a Provar XML test case that validates database state using DbConnect and SqlQuery steps.
|
|
368
|
+
|
|
369
|
+
This is a **database test**, NOT a Salesforce UI or Apex test. Do not use UiConnect, UiWithScreen, ApexConnect, or ApexCreateObject — use the database step types: DbConnect, SqlQuery, SetValues, AssertValues.
|
|
370
|
+
|
|
371
|
+
## Workflow
|
|
372
|
+
|
|
373
|
+
Follow these steps in order:
|
|
374
|
+
|
|
375
|
+
1. **Get corpus examples** — call \`provar.qualityhub.examples.retrieve\` with a query that includes "database DbConnect SqlQuery" plus keywords from the story (e.g. "database SQL Server verify record count"). Use the returned XML examples as the reference for correct step structure.
|
|
376
|
+
If the response has \`"count": 0\` with a \`"warning"\` field (API unavailable or not configured), fall back: read the \`provar://docs/step-reference\` MCP resource — specifically the Database Steps section — for the correct attribute schema, then continue.
|
|
377
|
+
|
|
378
|
+
2. **Generate the test case** — produce valid Provar XML. Apply these database-specific rules:
|
|
379
|
+
|
|
380
|
+
**DbConnect rules:**
|
|
381
|
+
- \`connectionName\` argument identifies the Connection Manager entry (e.g. \`"MyDatabase"\`).${connectionName ? `\n - Use connection name: ${connectionName}` : ''}
|
|
382
|
+
- \`connectionId\` argument MUST use \`valueClass="id"\` — NOT \`"string"\`. Using \`"string"\` causes a runtime type error.
|
|
383
|
+
- \`resultName\` sets the **connection handle** — the variable name used to refer to this open connection (e.g. \`"DbConnection"\`). Choose any valid identifier.
|
|
384
|
+
- This handle must be reused exactly as \`dbConnectionName\` on every SqlQuery step that uses this connection.
|
|
385
|
+
|
|
386
|
+
**SqlQuery rules:**
|
|
387
|
+
- \`dbConnectionName\` must exactly equal the \`resultName\` from the DbConnect step above.
|
|
388
|
+
- \`resultName\` names the variable that will hold the query result rows (e.g. \`"DbResults"\`).
|
|
389
|
+
|
|
390
|
+
**Accessing results in SetValues/AssertValues — critical:**
|
|
391
|
+
- To count result rows: use \`<value class="funcCall" id="Count">\` — NEVER use \`{Count(Var)}\` string expressions.
|
|
392
|
+
- To access a field from row N (0-based): use the structured variable path with a \`<filter class="index">\` — NEVER use \`{Var[0].Field}\` string expressions.
|
|
393
|
+
- String \`{...}\` expressions are stored verbatim and never evaluated. They will always produce wrong results.
|
|
394
|
+
|
|
395
|
+
**Pattern for extracting values from results:**
|
|
396
|
+
\`\`\`xml
|
|
397
|
+
<!-- Count rows -->
|
|
398
|
+
<value class="funcCall" id="Count">
|
|
399
|
+
<argument id="value">
|
|
400
|
+
<value class="variable"><path element="DbResults"/></value>
|
|
401
|
+
</argument>
|
|
402
|
+
</value>
|
|
403
|
+
|
|
404
|
+
<!-- Access field from row 0 -->
|
|
405
|
+
<value class="variable">
|
|
406
|
+
<path element="DbResults">
|
|
407
|
+
<filter class="index"><index valueClass="decimal">0</index></filter>
|
|
408
|
+
</path>
|
|
409
|
+
<path element="FieldName"/>
|
|
410
|
+
</value>
|
|
411
|
+
\`\`\`
|
|
412
|
+
|
|
413
|
+
3. **Write the file** — save the XML to the tests/ directory in the Provar project.
|
|
414
|
+
${projectHint(projectPath)}
|
|
415
|
+
${testName ? `Target file name: ${testName}.testcase` : 'Infer the file name from the story (snake_case).'}
|
|
416
|
+
|
|
417
|
+
4. **Validate** — call \`provar.testcase.validate\` on the saved file. If it reports errors, fix them and re-validate until the file passes clean.
|
|
418
|
+
|
|
419
|
+
5. **Report** — summarise:
|
|
420
|
+
- Which query/assertion was implemented
|
|
421
|
+
- The DbConnect resultName and SqlQuery dbConnectionName used (confirm they match)
|
|
422
|
+
- Any validation warnings
|
|
423
|
+
- Any aspects of the story that could not be automated (add \`<!-- TODO: manual verification — <reason> -->\` in the XML)
|
|
424
|
+
|
|
425
|
+
## Database Test Story
|
|
426
|
+
|
|
427
|
+
${story}
|
|
428
|
+
|
|
429
|
+
Begin with step 1: call provar.qualityhub.examples.retrieve with "database DbConnect SqlQuery" plus keywords from the story above.`,
|
|
430
|
+
},
|
|
431
|
+
},
|
|
432
|
+
],
|
|
433
|
+
}));
|
|
434
|
+
}
|
|
435
|
+
//# sourceMappingURL=loopPrompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loopPrompts.js","sourceRoot":"","sources":["../../../src/mcp/prompts/loopPrompts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
export declare function registerCrtMigrationPrompt(server: McpServer): void;
|
|
3
|
+
export declare function registerSeleniumMigrationPrompt(server: McpServer): void;
|
|
4
|
+
export declare function registerPlaywrightMigrationPrompt(server: McpServer): void;
|