@provartesting/provardx-cli 1.4.7 → 1.5.0-dev.1
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 +264 -9
- package/lib/commands/provar/automation/config/validate.js.map +1 -1
- package/lib/commands/provar/automation/project/validate.d.ts +14 -0
- package/lib/commands/provar/automation/project/validate.js +69 -0
- package/lib/commands/provar/automation/project/validate.js.map +1 -0
- package/lib/commands/provar/mcp/start.d.ts +16 -0
- package/lib/commands/provar/mcp/start.js +62 -0
- package/lib/commands/provar/mcp/start.js.map +1 -0
- package/lib/commands/provar/quality-hub/connect.d.ts +5 -0
- package/lib/commands/provar/quality-hub/connect.js +12 -0
- package/lib/commands/provar/quality-hub/connect.js.map +1 -0
- package/lib/commands/provar/quality-hub/display.d.ts +5 -0
- package/lib/commands/provar/quality-hub/display.js +12 -0
- package/lib/commands/provar/quality-hub/display.js.map +1 -0
- package/lib/commands/provar/quality-hub/open.d.ts +5 -0
- package/lib/commands/provar/quality-hub/open.js +12 -0
- package/lib/commands/provar/quality-hub/open.js.map +1 -0
- package/lib/commands/provar/quality-hub/test/run/abort.d.ts +5 -0
- package/lib/commands/provar/quality-hub/test/run/abort.js +12 -0
- package/lib/commands/provar/quality-hub/test/run/abort.js.map +1 -0
- package/lib/commands/provar/quality-hub/test/run/report.d.ts +5 -0
- package/lib/commands/provar/quality-hub/test/run/report.js +12 -0
- package/lib/commands/provar/quality-hub/test/run/report.js.map +1 -0
- package/lib/commands/provar/quality-hub/test/run.d.ts +5 -0
- package/lib/commands/provar/quality-hub/test/run.js +12 -0
- package/lib/commands/provar/quality-hub/test/run.js.map +1 -0
- package/lib/commands/provar/quality-hub/testcase/retrieve.d.ts +5 -0
- package/lib/commands/provar/quality-hub/testcase/retrieve.js +12 -0
- package/lib/commands/provar/quality-hub/testcase/retrieve.js.map +1 -0
- package/lib/mcp/licensing/algasClient.d.ts +19 -0
- package/lib/mcp/licensing/algasClient.js +144 -0
- package/lib/mcp/licensing/algasClient.js.map +1 -0
- package/lib/mcp/licensing/ideDetection.d.ts +34 -0
- package/lib/mcp/licensing/ideDetection.js +179 -0
- package/lib/mcp/licensing/ideDetection.js.map +1 -0
- package/lib/mcp/licensing/index.d.ts +5 -0
- package/lib/mcp/licensing/index.js +10 -0
- package/lib/mcp/licensing/index.js.map +1 -0
- package/lib/mcp/licensing/licenseCache.d.ts +20 -0
- package/lib/mcp/licensing/licenseCache.js +79 -0
- package/lib/mcp/licensing/licenseCache.js.map +1 -0
- package/lib/mcp/licensing/licenseError.d.ts +4 -0
- package/lib/mcp/licensing/licenseError.js +15 -0
- package/lib/mcp/licensing/licenseError.js.map +1 -0
- package/lib/mcp/licensing/licenseValidator.d.ts +33 -0
- package/lib/mcp/licensing/licenseValidator.js +103 -0
- package/lib/mcp/licensing/licenseValidator.js.map +1 -0
- package/lib/mcp/logging/logger.d.ts +7 -0
- package/lib/mcp/logging/logger.js +22 -0
- package/lib/mcp/logging/logger.js.map +1 -0
- package/lib/mcp/rules/page_object_validation_rules.json +344 -0
- package/lib/mcp/rules/provar_best_practices_rules.json +3192 -0
- package/lib/mcp/schemas/common.d.ts +20 -0
- package/lib/mcp/schemas/common.js +16 -0
- package/lib/mcp/schemas/common.js.map +1 -0
- package/lib/mcp/security/pathPolicy.d.ts +14 -0
- package/lib/mcp/security/pathPolicy.js +38 -0
- package/lib/mcp/security/pathPolicy.js.map +1 -0
- package/lib/mcp/server.d.ts +5 -0
- package/lib/mcp/server.js +59 -0
- package/lib/mcp/server.js.map +1 -0
- package/lib/mcp/tools/antTools.d.ts +21 -0
- package/lib/mcp/tools/antTools.js +602 -0
- package/lib/mcp/tools/antTools.js.map +1 -0
- package/lib/mcp/tools/automationTools.d.ts +14 -0
- package/lib/mcp/tools/automationTools.js +386 -0
- package/lib/mcp/tools/automationTools.js.map +1 -0
- package/lib/mcp/tools/bestPracticesEngine.d.ts +30 -0
- package/lib/mcp/tools/bestPracticesEngine.js +632 -0
- package/lib/mcp/tools/bestPracticesEngine.js.map +1 -0
- package/lib/mcp/tools/defectTools.d.ts +15 -0
- package/lib/mcp/tools/defectTools.js +199 -0
- package/lib/mcp/tools/defectTools.js.map +1 -0
- package/lib/mcp/tools/hierarchyValidate.d.ts +139 -0
- package/lib/mcp/tools/hierarchyValidate.js +540 -0
- package/lib/mcp/tools/hierarchyValidate.js.map +1 -0
- package/lib/mcp/tools/pageObjectGenerate.d.ts +3 -0
- package/lib/mcp/tools/pageObjectGenerate.js +153 -0
- package/lib/mcp/tools/pageObjectGenerate.js.map +1 -0
- package/lib/mcp/tools/pageObjectValidate.d.ts +18 -0
- package/lib/mcp/tools/pageObjectValidate.js +420 -0
- package/lib/mcp/tools/pageObjectValidate.js.map +1 -0
- package/lib/mcp/tools/projectInspect.d.ts +3 -0
- package/lib/mcp/tools/projectInspect.js +694 -0
- package/lib/mcp/tools/projectInspect.js.map +1 -0
- package/lib/mcp/tools/projectValidateFromPath.d.ts +3 -0
- package/lib/mcp/tools/projectValidateFromPath.js +153 -0
- package/lib/mcp/tools/projectValidateFromPath.js.map +1 -0
- package/lib/mcp/tools/propertiesTools.d.ts +7 -0
- package/lib/mcp/tools/propertiesTools.js +314 -0
- package/lib/mcp/tools/propertiesTools.js.map +1 -0
- package/lib/mcp/tools/qualityHubTools.d.ts +8 -0
- package/lib/mcp/tools/qualityHubTools.js +178 -0
- package/lib/mcp/tools/qualityHubTools.js.map +1 -0
- package/lib/mcp/tools/rcaTools.d.ts +4 -0
- package/lib/mcp/tools/rcaTools.js +620 -0
- package/lib/mcp/tools/rcaTools.js.map +1 -0
- package/lib/mcp/tools/sfSpawn.d.ts +28 -0
- package/lib/mcp/tools/sfSpawn.js +50 -0
- package/lib/mcp/tools/sfSpawn.js.map +1 -0
- package/lib/mcp/tools/testCaseGenerate.d.ts +3 -0
- package/lib/mcp/tools/testCaseGenerate.js +221 -0
- package/lib/mcp/tools/testCaseGenerate.js.map +1 -0
- package/lib/mcp/tools/testCaseValidate.d.ts +20 -0
- package/lib/mcp/tools/testCaseValidate.js +227 -0
- package/lib/mcp/tools/testCaseValidate.js.map +1 -0
- package/lib/mcp/tools/testPlanTools.d.ts +6 -0
- package/lib/mcp/tools/testPlanTools.js +311 -0
- package/lib/mcp/tools/testPlanTools.js.map +1 -0
- package/lib/mcp/tools/testPlanValidate.d.ts +2 -0
- package/lib/mcp/tools/testPlanValidate.js +75 -0
- package/lib/mcp/tools/testPlanValidate.js.map +1 -0
- package/lib/mcp/tools/testSuiteValidate.d.ts +2 -0
- package/lib/mcp/tools/testSuiteValidate.js +63 -0
- package/lib/mcp/tools/testSuiteValidate.js.map +1 -0
- package/lib/services/projectValidation.d.ts +119 -0
- package/lib/services/projectValidation.js +678 -0
- package/lib/services/projectValidation.js.map +1 -0
- package/messages/sf.provar.automation.project.validate.md +52 -0
- package/messages/sf.provar.mcp.start.md +74 -0
- package/oclif.manifest.json +1298 -1
- package/package.json +46 -23
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
export interface DefectCreateResult {
|
|
3
|
+
defectId: string;
|
|
4
|
+
tcDefectId: string;
|
|
5
|
+
execDefectId: string;
|
|
6
|
+
executionId: string;
|
|
7
|
+
testCaseId: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function createDefectsForRun(runId: string, targetOrg: string, failedTestFilter?: string[]): {
|
|
10
|
+
created: DefectCreateResult[];
|
|
11
|
+
skipped: number;
|
|
12
|
+
message: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function registerQualityHubDefectCreate(server: McpServer): void;
|
|
15
|
+
export declare function registerAllDefectTools(server: McpServer): void;
|
|
@@ -0,0 +1,199 @@
|
|
|
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
|
+
/* eslint-disable camelcase */
|
|
8
|
+
import { z } from 'zod';
|
|
9
|
+
import { makeError, makeRequestId } from '../schemas/common.js';
|
|
10
|
+
import { log } from '../logging/logger.js';
|
|
11
|
+
import { runSfCommand, soqlEscape } from './sfSpawn.js';
|
|
12
|
+
// ── SF CLI helpers ─────────────────────────────────────────────────────────────
|
|
13
|
+
function runSfArgs(args) {
|
|
14
|
+
const { stdout, exitCode } = runSfCommand(args);
|
|
15
|
+
return { stdout, exitCode };
|
|
16
|
+
}
|
|
17
|
+
function runQuery(soql, targetOrg) {
|
|
18
|
+
const { stdout } = runSfArgs([
|
|
19
|
+
'data', 'query',
|
|
20
|
+
'--query', soql,
|
|
21
|
+
'--target-org', targetOrg,
|
|
22
|
+
'--json',
|
|
23
|
+
]);
|
|
24
|
+
return JSON.parse(stdout);
|
|
25
|
+
}
|
|
26
|
+
function createRecord(sobject, values, targetOrg) {
|
|
27
|
+
const { stdout } = runSfArgs([
|
|
28
|
+
'data', 'create', 'record',
|
|
29
|
+
'--sobject', sobject,
|
|
30
|
+
'--values', values,
|
|
31
|
+
'--target-org', targetOrg,
|
|
32
|
+
'--json',
|
|
33
|
+
]);
|
|
34
|
+
const parsed = JSON.parse(stdout);
|
|
35
|
+
if (!parsed.result?.success) {
|
|
36
|
+
throw new Error(`Failed to create ${sobject}: ${stdout}`);
|
|
37
|
+
}
|
|
38
|
+
return parsed.result.id;
|
|
39
|
+
}
|
|
40
|
+
/** Strip characters unsafe for sf --values double-quoted strings and truncate. */
|
|
41
|
+
function safeText(value, maxLen = 200) {
|
|
42
|
+
if (value === null || value === undefined)
|
|
43
|
+
return '';
|
|
44
|
+
return String(value)
|
|
45
|
+
.replace(/"/g, "'")
|
|
46
|
+
.replace(/\n|\r/g, ' ')
|
|
47
|
+
.substring(0, maxLen);
|
|
48
|
+
}
|
|
49
|
+
export function createDefectsForRun(runId, targetOrg, failedTestFilter) {
|
|
50
|
+
// Step 1: resolve job record ID from tracking ID
|
|
51
|
+
const jobQuery = runQuery(`SELECT Id FROM provar__Test_Plan_Schedule_Job__c WHERE provar__Tracking_Id__c = '${soqlEscape(runId)}'`, targetOrg);
|
|
52
|
+
if (jobQuery.result.totalSize === 0) {
|
|
53
|
+
throw new Error(`No Test_Plan_Schedule_Job__c found with Tracking_Id__c = '${runId}'`);
|
|
54
|
+
}
|
|
55
|
+
const jobId = jobQuery.result.records[0].Id;
|
|
56
|
+
// Step 2: find Test_Cycle__c — carries browser + environment context
|
|
57
|
+
const cycleQuery = runQuery(`SELECT Id, provar__Web_Browser__c, provar__Browser_Version__c, provar__Environment_Text__c
|
|
58
|
+
FROM provar__Test_Cycle__c
|
|
59
|
+
WHERE provar__Test_Plan_Schedule_Job__c = '${soqlEscape(jobId)}'
|
|
60
|
+
LIMIT 1`, targetOrg);
|
|
61
|
+
const cycle = cycleQuery.result.records[0] ?? {};
|
|
62
|
+
const browser = safeText(cycle['provar__Web_Browser__c'], 100);
|
|
63
|
+
const browserVersion = safeText(cycle['provar__Browser_Version__c'], 100);
|
|
64
|
+
const environmentText = safeText(cycle['provar__Environment_Text__c'], 255);
|
|
65
|
+
const cycleId = String(cycle['Id'] ?? '');
|
|
66
|
+
if (!cycleId) {
|
|
67
|
+
throw new Error(`No Test_Cycle__c found for job ${jobId}`);
|
|
68
|
+
}
|
|
69
|
+
// Step 3: find failed Test_Execution__c records
|
|
70
|
+
const execQuery = runQuery(`SELECT Id, provar__Test_Case__c, provar__Tester__c
|
|
71
|
+
FROM provar__Test_Execution__c
|
|
72
|
+
WHERE provar__Test_Cycle__c = '${soqlEscape(cycleId)}'
|
|
73
|
+
AND provar__Status__c = 'Failed'`, targetOrg);
|
|
74
|
+
if (execQuery.result.totalSize === 0) {
|
|
75
|
+
return { created: [], skipped: 0, message: 'No failed test executions found for this run.' };
|
|
76
|
+
}
|
|
77
|
+
let executions = execQuery.result.records;
|
|
78
|
+
// Apply optional TC name filter (filter by ID prefix match — caller must resolve names to IDs first
|
|
79
|
+
// if needed; here we filter by TC record ID substring for flexibility)
|
|
80
|
+
if (failedTestFilter && failedTestFilter.length > 0) {
|
|
81
|
+
executions = executions.filter((e) => failedTestFilter.some((f) => String(e['provar__Test_Case__c']).includes(f) || f.includes(String(e['provar__Test_Case__c']))));
|
|
82
|
+
}
|
|
83
|
+
const created = [];
|
|
84
|
+
for (const exec of executions) {
|
|
85
|
+
const executionId = exec.Id;
|
|
86
|
+
const testCaseId = String(exec['provar__Test_Case__c'] ?? '');
|
|
87
|
+
const tester = safeText(exec['provar__Tester__c'], 100);
|
|
88
|
+
// Step 4: first failed step in this execution
|
|
89
|
+
const stepQuery = runQuery(`SELECT Id, provar__ActionObs__c, provar__Actual_Result__c, provar__Sequence_No__c, provar__Test_Step__c
|
|
90
|
+
FROM provar__Test_Step_Execution__c
|
|
91
|
+
WHERE provar__Test_Execution__c = '${soqlEscape(executionId)}'
|
|
92
|
+
AND provar__Result__c = 'Fail'
|
|
93
|
+
ORDER BY provar__Sequence_No__c ASC
|
|
94
|
+
LIMIT 1`, targetOrg);
|
|
95
|
+
const step = stepQuery.result.records[0] ?? {};
|
|
96
|
+
const stepExecutionId = step['Id'] ?? '';
|
|
97
|
+
const stepId = String(step['provar__Test_Step__c'] ?? '');
|
|
98
|
+
const stepAction = safeText(step['provar__ActionObs__c'], 200);
|
|
99
|
+
const stepResult = safeText(step['provar__Actual_Result__c'], 200);
|
|
100
|
+
const stepSeq = Number(step['provar__Sequence_No__c'] ?? 0);
|
|
101
|
+
const ctx = {
|
|
102
|
+
executionId,
|
|
103
|
+
testCaseId,
|
|
104
|
+
tester,
|
|
105
|
+
stepExecutionId: String(stepExecutionId),
|
|
106
|
+
stepId,
|
|
107
|
+
stepAction,
|
|
108
|
+
stepResult,
|
|
109
|
+
stepSeq,
|
|
110
|
+
browser,
|
|
111
|
+
browserVersion,
|
|
112
|
+
environment: environmentText,
|
|
113
|
+
};
|
|
114
|
+
// Step 5a: create Defect__c
|
|
115
|
+
const descLines = [
|
|
116
|
+
`Failure: ${ctx.stepResult || 'See test execution for details'}`,
|
|
117
|
+
`Step ${ctx.stepSeq}: ${ctx.stepAction}`,
|
|
118
|
+
`Browser: ${ctx.browser} ${ctx.browserVersion}`.trim(),
|
|
119
|
+
`Environment: ${ctx.environment}`,
|
|
120
|
+
`Tester: ${ctx.tester}`,
|
|
121
|
+
`Test Execution ID: ${ctx.executionId}`,
|
|
122
|
+
`Run ID: ${runId}`,
|
|
123
|
+
]
|
|
124
|
+
.filter((l) => l.split(': ')[1]?.trim())
|
|
125
|
+
.join(' | ');
|
|
126
|
+
const defectValues = `Name="TC Failure: ${safeText(testCaseId, 100)}" ` +
|
|
127
|
+
`provar__Description__c="${safeText(descLines, 2000)}" ` +
|
|
128
|
+
'provar__Status__c="Open"';
|
|
129
|
+
const defectId = createRecord('provar__Defect__c', defectValues, targetOrg);
|
|
130
|
+
// Step 5b: link TC → Defect
|
|
131
|
+
const tcDefectValues = `provar__Defect__c="${defectId}" ` +
|
|
132
|
+
`provar__Test_Case__c="${testCaseId}"` +
|
|
133
|
+
(stepId ? ` provar__Test_Step__c="${stepId}"` : '');
|
|
134
|
+
const tcDefectId = createRecord('provar__Test_Case_Defect__c', tcDefectValues, targetOrg);
|
|
135
|
+
// Step 5c: link Execution → Defect (with step execution if available)
|
|
136
|
+
const execDefectValues = `provar__Defect__c="${defectId}" ` +
|
|
137
|
+
`provar__Test_Execution__c="${executionId}"` +
|
|
138
|
+
(stepExecutionId ? ` provar__Test_Step_Execution__c="${stepExecutionId}"` : '');
|
|
139
|
+
const execDefectId = createRecord('provar__Test_Execution_Defect__c', execDefectValues, targetOrg);
|
|
140
|
+
log('info', 'defect created', { defectId, tcDefectId, execDefectId, executionId });
|
|
141
|
+
created.push({ defectId, tcDefectId, execDefectId, executionId, testCaseId });
|
|
142
|
+
}
|
|
143
|
+
const syncNote = 'If Jira or ADO sync is enabled in your Quality Hub org, these defects will sync automatically.';
|
|
144
|
+
return {
|
|
145
|
+
created,
|
|
146
|
+
skipped: execQuery.result.totalSize - created.length,
|
|
147
|
+
message: `Created ${created.length} defect(s) for run ${runId}. ${syncNote}`,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
// ── Tool registration ──────────────────────────────────────────────────────────
|
|
151
|
+
export function registerQualityHubDefectCreate(server) {
|
|
152
|
+
server.tool('provar.qualityhub.defect.create', [
|
|
153
|
+
'Create Defect__c records in Quality Hub for failed test executions in a given run.',
|
|
154
|
+
'Queries the run by Tracking_Id__c, finds failed Test_Execution__c records, creates a',
|
|
155
|
+
'Defect__c per failure (with description, step, browser, environment, tester), and links',
|
|
156
|
+
'it via Test_Case_Defect__c and Test_Execution_Defect__c junction records.',
|
|
157
|
+
'If Jira or ADO sync is configured in Quality Hub, defects sync to those systems automatically.',
|
|
158
|
+
].join(' '), {
|
|
159
|
+
run_id: z
|
|
160
|
+
.string()
|
|
161
|
+
.describe('Test run Tracking_Id__c value returned by provar.qualityhub.testrun'),
|
|
162
|
+
target_org: z.string().describe('SF org alias or username for the Quality Hub org'),
|
|
163
|
+
failed_tests: z
|
|
164
|
+
.array(z.string())
|
|
165
|
+
.optional()
|
|
166
|
+
.describe('Optional filter — list of Test_Case__c record ID substrings to restrict defect creation to specific failures'),
|
|
167
|
+
}, ({ run_id, target_org, failed_tests }) => {
|
|
168
|
+
const requestId = makeRequestId();
|
|
169
|
+
log('info', 'provar.qualityhub.defect.create', { requestId, run_id, target_org });
|
|
170
|
+
try {
|
|
171
|
+
const result = createDefectsForRun(run_id, target_org, failed_tests);
|
|
172
|
+
const response = { requestId, ...result };
|
|
173
|
+
return {
|
|
174
|
+
content: [{ type: 'text', text: JSON.stringify(response) }],
|
|
175
|
+
structuredContent: response,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
const error = err;
|
|
180
|
+
log('error', 'provar.qualityhub.defect.create failed', {
|
|
181
|
+
requestId,
|
|
182
|
+
error: error.message,
|
|
183
|
+
});
|
|
184
|
+
return {
|
|
185
|
+
isError: true,
|
|
186
|
+
content: [
|
|
187
|
+
{
|
|
188
|
+
type: 'text',
|
|
189
|
+
text: JSON.stringify(makeError(error.code ?? 'DEFECT_CREATE_FAILED', error.message, requestId, false)),
|
|
190
|
+
},
|
|
191
|
+
],
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
export function registerAllDefectTools(server) {
|
|
197
|
+
registerQualityHubDefectCreate(server);
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=defectTools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defectTools.js","sourceRoot":"","sources":["../../../src/mcp/tools/defectTools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import type { ValidationIssue } from '../schemas/common.js';
|
|
2
|
+
import type { BPViolation } from './bestPracticesEngine.js';
|
|
3
|
+
export interface TestCaseInput {
|
|
4
|
+
name: string;
|
|
5
|
+
/** XML content of the test case. The field `xml` (API standard) is accepted as an alias. */
|
|
6
|
+
xml_content?: string;
|
|
7
|
+
/** API-compatible alias for xml_content (Quality Hub batch validation API uses this field name). */
|
|
8
|
+
xml?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface TestSuiteInput {
|
|
11
|
+
name: string;
|
|
12
|
+
test_cases?: TestCaseInput[];
|
|
13
|
+
test_suites?: TestSuiteInput[];
|
|
14
|
+
test_case_count?: number;
|
|
15
|
+
}
|
|
16
|
+
export interface PlanMetadata {
|
|
17
|
+
objectives?: string;
|
|
18
|
+
in_scope?: string;
|
|
19
|
+
testing_methodology?: string;
|
|
20
|
+
acceptance_criteria?: string;
|
|
21
|
+
acceptable_pass_rate?: number;
|
|
22
|
+
environments?: string[];
|
|
23
|
+
test_data_strategy?: string;
|
|
24
|
+
risks?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface TestPlanInput {
|
|
27
|
+
name: string;
|
|
28
|
+
test_suites?: TestSuiteInput[];
|
|
29
|
+
test_cases?: TestCaseInput[];
|
|
30
|
+
test_suite_count?: number;
|
|
31
|
+
metadata?: PlanMetadata;
|
|
32
|
+
}
|
|
33
|
+
export interface ProjectContext {
|
|
34
|
+
connection_names?: string[];
|
|
35
|
+
environments?: string[];
|
|
36
|
+
secretsPasswordSet?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Number of keys in the .secrets file whose values are NOT wrapped in ENC1().
|
|
39
|
+
* Populated by provar.project.inspect → secrets_validation.unencrypted_key_count.
|
|
40
|
+
* Any value > 0 triggers PROJ-ENC-001.
|
|
41
|
+
*/
|
|
42
|
+
unencrypted_secret_count?: number;
|
|
43
|
+
}
|
|
44
|
+
export interface ProjectInput {
|
|
45
|
+
name: string;
|
|
46
|
+
test_plans?: TestPlanInput[];
|
|
47
|
+
test_suites?: TestSuiteInput[];
|
|
48
|
+
test_cases?: TestCaseInput[];
|
|
49
|
+
project_context?: ProjectContext;
|
|
50
|
+
/**
|
|
51
|
+
* Basenames (without extension) of every .testcase file found on disk, including
|
|
52
|
+
* callable tests (visibility="Internal") that have no plan instances. Populated
|
|
53
|
+
* by validateProjectFromPath so that checkCaseCalls can resolve caseCall references
|
|
54
|
+
* against the full on-disk corpus rather than only plan-registered test cases.
|
|
55
|
+
*/
|
|
56
|
+
all_disk_test_case_names?: string[];
|
|
57
|
+
}
|
|
58
|
+
export interface HierarchyViolation {
|
|
59
|
+
rule_id: string;
|
|
60
|
+
name: string;
|
|
61
|
+
description: string;
|
|
62
|
+
category: string;
|
|
63
|
+
severity: 'critical' | 'major' | 'minor' | 'info';
|
|
64
|
+
weight: number;
|
|
65
|
+
message: string;
|
|
66
|
+
recommendation: string;
|
|
67
|
+
applies_to: string[];
|
|
68
|
+
affected_files?: string[];
|
|
69
|
+
}
|
|
70
|
+
export interface TestCaseResult {
|
|
71
|
+
name: string;
|
|
72
|
+
level: 'test_case';
|
|
73
|
+
status: 'valid' | 'invalid' | 'error';
|
|
74
|
+
quality_score: number;
|
|
75
|
+
validity_score: number;
|
|
76
|
+
is_valid: boolean;
|
|
77
|
+
error_count: number;
|
|
78
|
+
warning_count: number;
|
|
79
|
+
step_count: number;
|
|
80
|
+
issues: ValidationIssue[];
|
|
81
|
+
/** Best-practice violations from the BP engine (DESIGN-*, REUSE-*, STRUCT-*, etc.) */
|
|
82
|
+
best_practices_violations: BPViolation[];
|
|
83
|
+
}
|
|
84
|
+
export interface SuiteResult {
|
|
85
|
+
name: string;
|
|
86
|
+
level: 'suite';
|
|
87
|
+
quality_score: number;
|
|
88
|
+
violations: HierarchyViolation[];
|
|
89
|
+
test_cases: TestCaseResult[];
|
|
90
|
+
test_suites: SuiteResult[];
|
|
91
|
+
}
|
|
92
|
+
export interface PlanResult {
|
|
93
|
+
name: string;
|
|
94
|
+
level: 'plan';
|
|
95
|
+
quality_score: number;
|
|
96
|
+
violations: HierarchyViolation[];
|
|
97
|
+
test_suites: SuiteResult[];
|
|
98
|
+
test_cases: TestCaseResult[];
|
|
99
|
+
}
|
|
100
|
+
export interface ProjectResult {
|
|
101
|
+
name: string;
|
|
102
|
+
level: 'project';
|
|
103
|
+
quality_score: number;
|
|
104
|
+
violations: HierarchyViolation[];
|
|
105
|
+
test_plans: PlanResult[];
|
|
106
|
+
test_suites: SuiteResult[];
|
|
107
|
+
test_cases: TestCaseResult[];
|
|
108
|
+
project_context: ProjectContext;
|
|
109
|
+
}
|
|
110
|
+
export interface HierarchySummary {
|
|
111
|
+
total_test_cases: number;
|
|
112
|
+
test_cases_valid: number;
|
|
113
|
+
test_cases_invalid: number;
|
|
114
|
+
test_cases_error: number;
|
|
115
|
+
total_violations: number;
|
|
116
|
+
violations_by_severity: {
|
|
117
|
+
critical: number;
|
|
118
|
+
major: number;
|
|
119
|
+
minor: number;
|
|
120
|
+
info: number;
|
|
121
|
+
};
|
|
122
|
+
violations_by_level: {
|
|
123
|
+
project: number;
|
|
124
|
+
plan: number;
|
|
125
|
+
suite: number;
|
|
126
|
+
test_case: number;
|
|
127
|
+
};
|
|
128
|
+
quality_score_avg: number;
|
|
129
|
+
quality_score_min: number | null;
|
|
130
|
+
quality_score_max: number | null;
|
|
131
|
+
}
|
|
132
|
+
export declare function computeViolationDeduction(violations: HierarchyViolation[]): number;
|
|
133
|
+
export declare function detectNamingStyle(nameStr: string): string;
|
|
134
|
+
export declare function checkNamingConsistency(names: string[], contextLabel: string, level: string, ruleId: string): HierarchyViolation[];
|
|
135
|
+
export declare function validateHierarchyTestCase(tc: TestCaseInput, qualityThreshold: number): TestCaseResult;
|
|
136
|
+
export declare function validateSuite(data: TestSuiteInput, qualityThreshold: number): SuiteResult;
|
|
137
|
+
export declare function validatePlan(data: TestPlanInput, qualityThreshold: number): PlanResult;
|
|
138
|
+
export declare function validateProject(data: ProjectInput, qualityThreshold: number): ProjectResult;
|
|
139
|
+
export declare function buildHierarchySummary(result: SuiteResult | PlanResult | ProjectResult): HierarchySummary;
|