@provartesting/provardx-cli 1.4.7 → 1.5.0-dev

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 (122) hide show
  1. package/README.md +264 -9
  2. package/lib/commands/provar/automation/config/validate.js.map +1 -1
  3. package/lib/commands/provar/automation/project/validate.d.ts +14 -0
  4. package/lib/commands/provar/automation/project/validate.js +69 -0
  5. package/lib/commands/provar/automation/project/validate.js.map +1 -0
  6. package/lib/commands/provar/mcp/start.d.ts +16 -0
  7. package/lib/commands/provar/mcp/start.js +62 -0
  8. package/lib/commands/provar/mcp/start.js.map +1 -0
  9. package/lib/commands/provar/quality-hub/connect.d.ts +5 -0
  10. package/lib/commands/provar/quality-hub/connect.js +12 -0
  11. package/lib/commands/provar/quality-hub/connect.js.map +1 -0
  12. package/lib/commands/provar/quality-hub/display.d.ts +5 -0
  13. package/lib/commands/provar/quality-hub/display.js +12 -0
  14. package/lib/commands/provar/quality-hub/display.js.map +1 -0
  15. package/lib/commands/provar/quality-hub/open.d.ts +5 -0
  16. package/lib/commands/provar/quality-hub/open.js +12 -0
  17. package/lib/commands/provar/quality-hub/open.js.map +1 -0
  18. package/lib/commands/provar/quality-hub/test/run/abort.d.ts +5 -0
  19. package/lib/commands/provar/quality-hub/test/run/abort.js +12 -0
  20. package/lib/commands/provar/quality-hub/test/run/abort.js.map +1 -0
  21. package/lib/commands/provar/quality-hub/test/run/report.d.ts +5 -0
  22. package/lib/commands/provar/quality-hub/test/run/report.js +12 -0
  23. package/lib/commands/provar/quality-hub/test/run/report.js.map +1 -0
  24. package/lib/commands/provar/quality-hub/test/run.d.ts +5 -0
  25. package/lib/commands/provar/quality-hub/test/run.js +12 -0
  26. package/lib/commands/provar/quality-hub/test/run.js.map +1 -0
  27. package/lib/commands/provar/quality-hub/testcase/retrieve.d.ts +5 -0
  28. package/lib/commands/provar/quality-hub/testcase/retrieve.js +12 -0
  29. package/lib/commands/provar/quality-hub/testcase/retrieve.js.map +1 -0
  30. package/lib/mcp/licensing/algasClient.d.ts +19 -0
  31. package/lib/mcp/licensing/algasClient.js +144 -0
  32. package/lib/mcp/licensing/algasClient.js.map +1 -0
  33. package/lib/mcp/licensing/ideDetection.d.ts +34 -0
  34. package/lib/mcp/licensing/ideDetection.js +179 -0
  35. package/lib/mcp/licensing/ideDetection.js.map +1 -0
  36. package/lib/mcp/licensing/index.d.ts +5 -0
  37. package/lib/mcp/licensing/index.js +10 -0
  38. package/lib/mcp/licensing/index.js.map +1 -0
  39. package/lib/mcp/licensing/licenseCache.d.ts +20 -0
  40. package/lib/mcp/licensing/licenseCache.js +79 -0
  41. package/lib/mcp/licensing/licenseCache.js.map +1 -0
  42. package/lib/mcp/licensing/licenseError.d.ts +4 -0
  43. package/lib/mcp/licensing/licenseError.js +15 -0
  44. package/lib/mcp/licensing/licenseError.js.map +1 -0
  45. package/lib/mcp/licensing/licenseValidator.d.ts +33 -0
  46. package/lib/mcp/licensing/licenseValidator.js +103 -0
  47. package/lib/mcp/licensing/licenseValidator.js.map +1 -0
  48. package/lib/mcp/logging/logger.d.ts +7 -0
  49. package/lib/mcp/logging/logger.js +22 -0
  50. package/lib/mcp/logging/logger.js.map +1 -0
  51. package/lib/mcp/rules/page_object_validation_rules.json +344 -0
  52. package/lib/mcp/rules/provar_best_practices_rules.json +3192 -0
  53. package/lib/mcp/schemas/common.d.ts +20 -0
  54. package/lib/mcp/schemas/common.js +16 -0
  55. package/lib/mcp/schemas/common.js.map +1 -0
  56. package/lib/mcp/security/pathPolicy.d.ts +14 -0
  57. package/lib/mcp/security/pathPolicy.js +38 -0
  58. package/lib/mcp/security/pathPolicy.js.map +1 -0
  59. package/lib/mcp/server.d.ts +5 -0
  60. package/lib/mcp/server.js +59 -0
  61. package/lib/mcp/server.js.map +1 -0
  62. package/lib/mcp/tools/antTools.d.ts +21 -0
  63. package/lib/mcp/tools/antTools.js +602 -0
  64. package/lib/mcp/tools/antTools.js.map +1 -0
  65. package/lib/mcp/tools/automationTools.d.ts +14 -0
  66. package/lib/mcp/tools/automationTools.js +386 -0
  67. package/lib/mcp/tools/automationTools.js.map +1 -0
  68. package/lib/mcp/tools/bestPracticesEngine.d.ts +30 -0
  69. package/lib/mcp/tools/bestPracticesEngine.js +632 -0
  70. package/lib/mcp/tools/bestPracticesEngine.js.map +1 -0
  71. package/lib/mcp/tools/defectTools.d.ts +15 -0
  72. package/lib/mcp/tools/defectTools.js +199 -0
  73. package/lib/mcp/tools/defectTools.js.map +1 -0
  74. package/lib/mcp/tools/hierarchyValidate.d.ts +139 -0
  75. package/lib/mcp/tools/hierarchyValidate.js +540 -0
  76. package/lib/mcp/tools/hierarchyValidate.js.map +1 -0
  77. package/lib/mcp/tools/pageObjectGenerate.d.ts +3 -0
  78. package/lib/mcp/tools/pageObjectGenerate.js +153 -0
  79. package/lib/mcp/tools/pageObjectGenerate.js.map +1 -0
  80. package/lib/mcp/tools/pageObjectValidate.d.ts +18 -0
  81. package/lib/mcp/tools/pageObjectValidate.js +420 -0
  82. package/lib/mcp/tools/pageObjectValidate.js.map +1 -0
  83. package/lib/mcp/tools/projectInspect.d.ts +3 -0
  84. package/lib/mcp/tools/projectInspect.js +694 -0
  85. package/lib/mcp/tools/projectInspect.js.map +1 -0
  86. package/lib/mcp/tools/projectValidateFromPath.d.ts +3 -0
  87. package/lib/mcp/tools/projectValidateFromPath.js +153 -0
  88. package/lib/mcp/tools/projectValidateFromPath.js.map +1 -0
  89. package/lib/mcp/tools/propertiesTools.d.ts +7 -0
  90. package/lib/mcp/tools/propertiesTools.js +314 -0
  91. package/lib/mcp/tools/propertiesTools.js.map +1 -0
  92. package/lib/mcp/tools/qualityHubTools.d.ts +8 -0
  93. package/lib/mcp/tools/qualityHubTools.js +178 -0
  94. package/lib/mcp/tools/qualityHubTools.js.map +1 -0
  95. package/lib/mcp/tools/rcaTools.d.ts +4 -0
  96. package/lib/mcp/tools/rcaTools.js +620 -0
  97. package/lib/mcp/tools/rcaTools.js.map +1 -0
  98. package/lib/mcp/tools/sfSpawn.d.ts +28 -0
  99. package/lib/mcp/tools/sfSpawn.js +50 -0
  100. package/lib/mcp/tools/sfSpawn.js.map +1 -0
  101. package/lib/mcp/tools/testCaseGenerate.d.ts +3 -0
  102. package/lib/mcp/tools/testCaseGenerate.js +221 -0
  103. package/lib/mcp/tools/testCaseGenerate.js.map +1 -0
  104. package/lib/mcp/tools/testCaseValidate.d.ts +20 -0
  105. package/lib/mcp/tools/testCaseValidate.js +227 -0
  106. package/lib/mcp/tools/testCaseValidate.js.map +1 -0
  107. package/lib/mcp/tools/testPlanTools.d.ts +6 -0
  108. package/lib/mcp/tools/testPlanTools.js +311 -0
  109. package/lib/mcp/tools/testPlanTools.js.map +1 -0
  110. package/lib/mcp/tools/testPlanValidate.d.ts +2 -0
  111. package/lib/mcp/tools/testPlanValidate.js +75 -0
  112. package/lib/mcp/tools/testPlanValidate.js.map +1 -0
  113. package/lib/mcp/tools/testSuiteValidate.d.ts +2 -0
  114. package/lib/mcp/tools/testSuiteValidate.js +63 -0
  115. package/lib/mcp/tools/testSuiteValidate.js.map +1 -0
  116. package/lib/services/projectValidation.d.ts +119 -0
  117. package/lib/services/projectValidation.js +678 -0
  118. package/lib/services/projectValidation.js.map +1 -0
  119. package/messages/sf.provar.automation.project.validate.md +52 -0
  120. package/messages/sf.provar.mcp.start.md +74 -0
  121. package/oclif.manifest.json +1298 -1
  122. package/package.json +29 -15
@@ -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;