@skyramp/mcp 0.2.6 → 0.2.7
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/build/commands/commandLibrary.d.ts +12 -0
- package/build/commands/recommendTestsAndExecuteCommand.d.ts +2 -0
- package/build/commands/testThisEndpointCommand.d.ts +2 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +1 -2
- package/build/playwright/PlaywrightTraceService.d.ts +32 -0
- package/build/playwright/index.d.ts +3 -0
- package/build/playwright/registerPlaywrightTools.d.ts +8 -0
- package/build/playwright/registerPlaywrightTools.js +12 -11
- package/build/playwright/traceRecordingPrompt.d.ts +13 -0
- package/build/playwright/traceRecordingPrompt.js +3 -11
- package/build/prompts/code-reuse.d.ts +1 -0
- package/build/prompts/enhance-assertions/contractProviderAssertionsPrompt.d.ts +2 -0
- package/build/prompts/enhance-assertions/integrationAssertionsPrompt.d.ts +2 -0
- package/build/prompts/enhance-assertions/sharedAssertionRules.d.ts +15 -0
- package/build/prompts/enhance-assertions/uiAssertionsPrompt.d.ts +2 -0
- package/build/prompts/fix-error-prompt.d.ts +1 -0
- package/build/prompts/initialize-workspace/initializeWorkspacePrompt.d.ts +1 -0
- package/build/prompts/modularization/integration-test-modularization.d.ts +1 -0
- package/build/prompts/modularization/ui-test-modularization.d.ts +1 -0
- package/build/prompts/personas.d.ts +21 -0
- package/build/prompts/pom-aware-code-reuse.d.ts +1 -0
- package/build/prompts/startTraceCollectionPrompts.d.ts +2 -0
- package/build/prompts/test-maintenance/actionsInstructions.d.ts +35 -0
- package/build/prompts/test-maintenance/drift-analysis-prompt.d.ts +4 -0
- package/build/prompts/test-maintenance/driftAnalysisSections.d.ts +13 -0
- package/build/prompts/test-recommendation/analysisOutputPrompt.d.ts +84 -0
- package/build/prompts/test-recommendation/analysisOutputPrompt.test.d.ts +1 -0
- package/build/prompts/test-recommendation/analysisOutputPrompt.test.js +1 -0
- package/build/prompts/test-recommendation/diffExecutionPlan.d.ts +17 -0
- package/build/prompts/test-recommendation/diffExecutionPlan.js +7 -16
- package/build/prompts/test-recommendation/fullRepoCatalog.d.ts +7 -0
- package/build/prompts/test-recommendation/mergeEnrichedScenarios.test.d.ts +1 -0
- package/build/prompts/test-recommendation/mergeEnrichedScenarios.test.js +1 -0
- package/build/prompts/test-recommendation/promptPlan.d.ts +203 -0
- package/build/prompts/test-recommendation/promptPlan.test.d.ts +1 -0
- package/build/prompts/test-recommendation/recommendationSections.d.ts +35 -0
- package/build/prompts/test-recommendation/recommendationShared.d.ts +31 -0
- package/build/prompts/test-recommendation/registerRecommendTestsPrompt.d.ts +7 -0
- package/build/prompts/test-recommendation/scopeAssessment.d.ts +55 -0
- package/build/prompts/test-recommendation/scopeAssessment.js +2 -2
- package/build/prompts/test-recommendation/scopeAssessment.test.d.ts +1 -0
- package/build/prompts/test-recommendation/scopeAssessment.test.js +1 -0
- package/build/prompts/test-recommendation/test-recommendation-prompt.d.ts +6 -0
- package/build/prompts/test-recommendation/test-recommendation-prompt.js +4 -4
- package/build/prompts/test-recommendation/test-recommendation-prompt.test.d.ts +1 -0
- package/build/prompts/test-recommendation/test-recommendation-prompt.test.js +6 -99
- package/build/prompts/testbot/testbot-prompts.d.ts +11 -0
- package/build/prompts/testbot/testbot-prompts.js +198 -34
- package/build/prompts/testbot/testbot-prompts.test.d.ts +1 -0
- package/build/prompts/testbot/testbot-prompts.test.js +15 -73
- package/build/resources/analysisResources.d.ts +17 -0
- package/build/resources/progressResource.d.ts +2 -0
- package/build/resources/testbotResource.d.ts +2 -0
- package/build/services/AnalyticsService.d.ts +13 -0
- package/build/services/AnalyticsService.test.d.ts +1 -0
- package/build/services/AnalyticsService.test.js +86 -0
- package/build/services/ModularizationService.d.ts +11 -0
- package/build/services/ScenarioGenerationService.d.ts +37 -0
- package/build/services/ScenarioGenerationService.integration.test.d.ts +1 -0
- package/build/services/ScenarioGenerationService.integration.test.js +4 -0
- package/build/services/ScenarioGenerationService.test.d.ts +1 -0
- package/build/services/TestDiscoveryService.d.ts +128 -0
- package/build/services/TestDiscoveryService.test.d.ts +1 -0
- package/build/services/TestDiscoveryService.test.js +4 -3
- package/build/services/TestExecutionService.d.ts +46 -0
- package/build/services/TestExecutionService.test.d.ts +1 -0
- package/build/services/TestExecutionService.test.js +33 -25
- package/build/services/TestGenerationService.d.ts +56 -0
- package/build/services/TestGenerationService.test.d.ts +1 -0
- package/build/services/TestGenerationService.test.js +10 -8
- package/build/services/containerEnv.d.ts +14 -0
- package/build/tool-phase-coverage.test.d.ts +1 -0
- package/build/tool-phase-coverage.test.js +2 -0
- package/build/tool-phases.d.ts +38 -0
- package/build/tools/auth/loginTool.d.ts +2 -0
- package/build/tools/auth/logoutTool.d.ts +2 -0
- package/build/tools/code-refactor/codeReuseTool.d.ts +2 -0
- package/build/tools/code-refactor/enhanceAssertionsTool.d.ts +2 -0
- package/build/tools/code-refactor/modularizationTool.d.ts +2 -0
- package/build/tools/executeSkyrampTestTool.d.ts +2 -0
- package/build/tools/fixErrorTool.d.ts +2 -0
- package/build/tools/generate-tests/generateBatchScenarioRestTool.d.ts +45 -0
- package/build/tools/generate-tests/generateBatchScenarioRestTool.test.d.ts +1 -0
- package/build/tools/generate-tests/generateBatchScenarioRestTool.test.js +11 -9
- package/build/tools/generate-tests/generateContractRestTool.d.ts +31 -0
- package/build/tools/generate-tests/generateE2ERestTool.d.ts +13 -0
- package/build/tools/generate-tests/generateFuzzRestTool.d.ts +10 -0
- package/build/tools/generate-tests/generateIntegrationRestTool.d.ts +16 -0
- package/build/tools/generate-tests/generateLoadRestTool.d.ts +18 -0
- package/build/tools/generate-tests/generateLoadRestTool.test.d.ts +1 -0
- package/build/tools/generate-tests/generateMockRestTool.d.ts +64 -0
- package/build/tools/generate-tests/generateSmokeRestTool.d.ts +8 -0
- package/build/tools/generate-tests/generateUIRestTool.d.ts +14 -0
- package/build/tools/generate-tests/generateUIRestTool.js +1 -1
- package/build/tools/generate-tests/loadTestSchema.d.ts +39 -0
- package/build/tools/one-click/oneClickTool.d.ts +11 -0
- package/build/tools/submitReportTool.d.ts +384 -0
- package/build/tools/submitReportTool.js +144 -2
- package/build/tools/submitReportTool.test.d.ts +1 -0
- package/build/tools/submitReportTool.test.js +215 -5
- package/build/tools/test-management/actionsTool.d.ts +10 -0
- package/build/tools/test-management/analyzeChangesTool.d.ts +27 -0
- package/build/tools/test-management/analyzeChangesTool.js +44 -7
- package/build/tools/test-management/analyzeChangesTool.test.d.ts +1 -0
- package/build/tools/test-management/analyzeChangesTool.test.js +76 -39
- package/build/tools/test-management/analyzeTestHealthTool.d.ts +2 -0
- package/build/tools/test-management/index.d.ts +3 -0
- package/build/tools/test-management/index.js +0 -1
- package/build/tools/trace/resolveSaveStoragePath.d.ts +7 -0
- package/build/tools/trace/resolveSaveStoragePath.test.d.ts +1 -0
- package/build/tools/trace/resolveSessionPaths.d.ts +40 -0
- package/build/tools/trace/resolveSessionPaths.test.d.ts +1 -0
- package/build/tools/trace/sessionState.d.ts +2 -0
- package/build/tools/trace/sessionState.test.d.ts +1 -0
- package/build/tools/trace/startTraceCollectionTool.d.ts +2 -0
- package/build/tools/trace/stopTraceCollectionTool.d.ts +2 -0
- package/build/tools/workspace/initScanWorkspaceTool.d.ts +4 -0
- package/build/tools/workspace/initializeWorkspaceTool.d.ts +2 -0
- package/build/tools/workspace/initializeWorkspaceTool.test.d.ts +1 -0
- package/build/tools/workspace/initializeWorkspaceTool.test.js +134 -0
- package/build/types/OneClickCommands.d.ts +68 -0
- package/build/types/RepositoryAnalysis.d.ts +3004 -0
- package/build/types/TestAnalysis.d.ts +96 -0
- package/build/types/TestExecution.d.ts +53 -0
- package/build/types/TestRecommendation.d.ts +12 -0
- package/build/types/TestTypes.d.ts +234 -0
- package/build/utils/AnalysisStateManager.d.ts +182 -0
- package/build/utils/AnalysisStateManager.test.d.ts +1 -0
- package/build/utils/analyze-openapi.d.ts +1 -0
- package/build/utils/branchDiff.d.ts +18 -0
- package/build/utils/dartRouteExtractor.d.ts +45 -0
- package/build/utils/dartRouteExtractor.test.d.ts +1 -0
- package/build/utils/docker.d.ts +19 -0
- package/build/utils/docker.test.d.ts +1 -0
- package/build/utils/docker.test.js +10 -9
- package/build/utils/featureFlags.d.ts +37 -0
- package/build/utils/featureFlags.test.d.ts +1 -0
- package/build/utils/gitStaging.d.ts +24 -0
- package/build/utils/gitStaging.test.d.ts +1 -0
- package/build/utils/gitStaging.test.js +13 -7
- package/build/utils/httpDefaults.d.ts +10 -0
- package/build/utils/httpDefaults.test.d.ts +1 -0
- package/build/utils/initAgent.d.ts +36 -0
- package/build/utils/language-helper.d.ts +6 -0
- package/build/utils/logger.d.ts +11 -0
- package/build/utils/normalizeParams.d.ts +14 -0
- package/build/utils/normalizeSkyrampImports.d.ts +13 -0
- package/build/utils/pr-comment-parser.d.ts +31 -0
- package/build/utils/pr-comment-parser.test.d.ts +1 -0
- package/build/utils/pr-comment-parser.test.js +6 -5
- package/build/utils/projectMetadata.d.ts +15 -0
- package/build/utils/projectMetadata.test.d.ts +1 -0
- package/build/utils/proxy-terminal.d.ts +2 -0
- package/build/utils/repoScanner.d.ts +27 -0
- package/build/utils/repoScanner.test.d.ts +1 -0
- package/build/utils/routeParsers.d.ts +63 -0
- package/build/utils/routeParsers.test.d.ts +1 -0
- package/build/utils/scenarioDrafting.d.ts +71 -0
- package/build/utils/scenarioDrafting.test.d.ts +1 -0
- package/build/utils/skyrampMdContent.d.ts +5 -0
- package/build/utils/sourceRouteExtractor.d.ts +48 -0
- package/build/utils/sourceRouteExtractor.test.d.ts +1 -0
- package/build/utils/telemetry.d.ts +32 -0
- package/build/utils/telemetry.test.d.ts +1 -0
- package/build/utils/trace-parser.d.ts +32 -0
- package/build/utils/trace-parser.test.d.ts +6 -0
- package/build/utils/uiPageEnumerator.d.ts +146 -0
- package/build/utils/uiPageEnumerator.js +58 -14
- package/build/utils/uiPageEnumerator.test.d.ts +1 -0
- package/build/utils/uiPageEnumerator.test.js +223 -43
- package/build/utils/utils.d.ts +39 -0
- package/build/utils/utils.test.d.ts +1 -0
- package/build/utils/versions.d.ts +3 -0
- package/build/utils/versions.js +1 -1
- package/build/utils/workspaceAuth.d.ts +127 -0
- package/build/utils/workspaceAuth.test.d.ts +1 -0
- package/build/utils/workspaceAuth.test.js +25 -25
- package/build/workspace/index.d.ts +1 -0
- package/build/workspace/workspace.d.ts +390 -0
- package/build/workspace/workspace.test.d.ts +1 -0
- package/package.json +8 -3
- package/build/tools/test-management/uiAnalyzeChangesTool.js +0 -155
- package/build/tools/test-management/uiAnalyzeChangesTool.test.js +0 -147
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { TestType, HttpMethod } from "../types/TestTypes.js";
|
|
4
|
+
export declare const targetElementSchema: z.ZodObject<{
|
|
5
|
+
role: z.ZodString;
|
|
6
|
+
accessibleName: z.ZodString;
|
|
7
|
+
testId: z.ZodNullable<z.ZodString>;
|
|
8
|
+
stableId: z.ZodNullable<z.ZodString>;
|
|
9
|
+
contextText: z.ZodNullable<z.ZodArray<z.ZodString, "many">>;
|
|
10
|
+
mutability: z.ZodOptional<z.ZodEnum<["mutable", "immutable", "unknown"]>>;
|
|
11
|
+
widgetType: z.ZodOptional<z.ZodEnum<["native", "custom", "unknown"]>>;
|
|
12
|
+
}, "strip", z.ZodTypeAny, {
|
|
13
|
+
role: string;
|
|
14
|
+
accessibleName: string;
|
|
15
|
+
testId: string | null;
|
|
16
|
+
stableId: string | null;
|
|
17
|
+
contextText: string[] | null;
|
|
18
|
+
mutability?: "unknown" | "mutable" | "immutable" | undefined;
|
|
19
|
+
widgetType?: "custom" | "unknown" | "native" | undefined;
|
|
20
|
+
}, {
|
|
21
|
+
role: string;
|
|
22
|
+
accessibleName: string;
|
|
23
|
+
testId: string | null;
|
|
24
|
+
stableId: string | null;
|
|
25
|
+
contextText: string[] | null;
|
|
26
|
+
mutability?: "unknown" | "mutable" | "immutable" | undefined;
|
|
27
|
+
widgetType?: "custom" | "unknown" | "native" | undefined;
|
|
28
|
+
}>;
|
|
29
|
+
export declare const pageContextSchema: z.ZodObject<{
|
|
30
|
+
url: z.ZodString;
|
|
31
|
+
pageHash: z.ZodOptional<z.ZodString>;
|
|
32
|
+
}, "strip", z.ZodTypeAny, {
|
|
33
|
+
url: string;
|
|
34
|
+
pageHash?: string | undefined;
|
|
35
|
+
}, {
|
|
36
|
+
url: string;
|
|
37
|
+
pageHash?: string | undefined;
|
|
38
|
+
}>;
|
|
39
|
+
export declare const newTestSchema: z.ZodEffects<z.ZodObject<{
|
|
40
|
+
testId: z.ZodString;
|
|
41
|
+
testType: z.ZodNativeEnum<typeof TestType>;
|
|
42
|
+
category: z.ZodEffects<z.ZodEnum<["business_rule", "security_boundary", "data_integrity", "breaking_change", "auth", "error_handling", "workflow", "data_validation", "crud"]>, "breaking_change" | "business_rule" | "security_boundary" | "data_integrity" | "auth" | "error_handling" | "workflow" | "data_validation" | "crud", unknown>;
|
|
43
|
+
endpoint: z.ZodString;
|
|
44
|
+
fileName: z.ZodString;
|
|
45
|
+
description: z.ZodOptional<z.ZodString>;
|
|
46
|
+
scenarioFile: z.ZodOptional<z.ZodString>;
|
|
47
|
+
traceFile: z.ZodOptional<z.ZodString>;
|
|
48
|
+
frontendTrace: z.ZodOptional<z.ZodString>;
|
|
49
|
+
reasoning: z.ZodString;
|
|
50
|
+
targetElements: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
51
|
+
role: z.ZodString;
|
|
52
|
+
accessibleName: z.ZodString;
|
|
53
|
+
testId: z.ZodNullable<z.ZodString>;
|
|
54
|
+
stableId: z.ZodNullable<z.ZodString>;
|
|
55
|
+
contextText: z.ZodNullable<z.ZodArray<z.ZodString, "many">>;
|
|
56
|
+
mutability: z.ZodOptional<z.ZodEnum<["mutable", "immutable", "unknown"]>>;
|
|
57
|
+
widgetType: z.ZodOptional<z.ZodEnum<["native", "custom", "unknown"]>>;
|
|
58
|
+
}, "strip", z.ZodTypeAny, {
|
|
59
|
+
role: string;
|
|
60
|
+
accessibleName: string;
|
|
61
|
+
testId: string | null;
|
|
62
|
+
stableId: string | null;
|
|
63
|
+
contextText: string[] | null;
|
|
64
|
+
mutability?: "unknown" | "mutable" | "immutable" | undefined;
|
|
65
|
+
widgetType?: "custom" | "unknown" | "native" | undefined;
|
|
66
|
+
}, {
|
|
67
|
+
role: string;
|
|
68
|
+
accessibleName: string;
|
|
69
|
+
testId: string | null;
|
|
70
|
+
stableId: string | null;
|
|
71
|
+
contextText: string[] | null;
|
|
72
|
+
mutability?: "unknown" | "mutable" | "immutable" | undefined;
|
|
73
|
+
widgetType?: "custom" | "unknown" | "native" | undefined;
|
|
74
|
+
}>, "many">>>;
|
|
75
|
+
pageContext: z.ZodOptional<z.ZodObject<{
|
|
76
|
+
url: z.ZodString;
|
|
77
|
+
pageHash: z.ZodOptional<z.ZodString>;
|
|
78
|
+
}, "strip", z.ZodTypeAny, {
|
|
79
|
+
url: string;
|
|
80
|
+
pageHash?: string | undefined;
|
|
81
|
+
}, {
|
|
82
|
+
url: string;
|
|
83
|
+
pageHash?: string | undefined;
|
|
84
|
+
}>>;
|
|
85
|
+
}, "strip", z.ZodTypeAny, {
|
|
86
|
+
testType: TestType;
|
|
87
|
+
category: "breaking_change" | "business_rule" | "security_boundary" | "data_integrity" | "auth" | "error_handling" | "workflow" | "data_validation" | "crud";
|
|
88
|
+
fileName: string;
|
|
89
|
+
endpoint: string;
|
|
90
|
+
testId: string;
|
|
91
|
+
reasoning: string;
|
|
92
|
+
description?: string | undefined;
|
|
93
|
+
traceFile?: string | undefined;
|
|
94
|
+
scenarioFile?: string | undefined;
|
|
95
|
+
frontendTrace?: string | undefined;
|
|
96
|
+
targetElements?: {
|
|
97
|
+
role: string;
|
|
98
|
+
accessibleName: string;
|
|
99
|
+
testId: string | null;
|
|
100
|
+
stableId: string | null;
|
|
101
|
+
contextText: string[] | null;
|
|
102
|
+
mutability?: "unknown" | "mutable" | "immutable" | undefined;
|
|
103
|
+
widgetType?: "custom" | "unknown" | "native" | undefined;
|
|
104
|
+
}[] | null | undefined;
|
|
105
|
+
pageContext?: {
|
|
106
|
+
url: string;
|
|
107
|
+
pageHash?: string | undefined;
|
|
108
|
+
} | undefined;
|
|
109
|
+
}, {
|
|
110
|
+
testType: TestType;
|
|
111
|
+
fileName: string;
|
|
112
|
+
endpoint: string;
|
|
113
|
+
testId: string;
|
|
114
|
+
reasoning: string;
|
|
115
|
+
description?: string | undefined;
|
|
116
|
+
category?: unknown;
|
|
117
|
+
traceFile?: string | undefined;
|
|
118
|
+
scenarioFile?: string | undefined;
|
|
119
|
+
frontendTrace?: string | undefined;
|
|
120
|
+
targetElements?: {
|
|
121
|
+
role: string;
|
|
122
|
+
accessibleName: string;
|
|
123
|
+
testId: string | null;
|
|
124
|
+
stableId: string | null;
|
|
125
|
+
contextText: string[] | null;
|
|
126
|
+
mutability?: "unknown" | "mutable" | "immutable" | undefined;
|
|
127
|
+
widgetType?: "custom" | "unknown" | "native" | undefined;
|
|
128
|
+
}[] | null | undefined;
|
|
129
|
+
pageContext?: {
|
|
130
|
+
url: string;
|
|
131
|
+
pageHash?: string | undefined;
|
|
132
|
+
} | undefined;
|
|
133
|
+
}>, {
|
|
134
|
+
testType: TestType;
|
|
135
|
+
category: "breaking_change" | "business_rule" | "security_boundary" | "data_integrity" | "auth" | "error_handling" | "workflow" | "data_validation" | "crud";
|
|
136
|
+
fileName: string;
|
|
137
|
+
endpoint: string;
|
|
138
|
+
testId: string;
|
|
139
|
+
reasoning: string;
|
|
140
|
+
description?: string | undefined;
|
|
141
|
+
traceFile?: string | undefined;
|
|
142
|
+
scenarioFile?: string | undefined;
|
|
143
|
+
frontendTrace?: string | undefined;
|
|
144
|
+
targetElements?: {
|
|
145
|
+
role: string;
|
|
146
|
+
accessibleName: string;
|
|
147
|
+
testId: string | null;
|
|
148
|
+
stableId: string | null;
|
|
149
|
+
contextText: string[] | null;
|
|
150
|
+
mutability?: "unknown" | "mutable" | "immutable" | undefined;
|
|
151
|
+
widgetType?: "custom" | "unknown" | "native" | undefined;
|
|
152
|
+
}[] | null | undefined;
|
|
153
|
+
pageContext?: {
|
|
154
|
+
url: string;
|
|
155
|
+
pageHash?: string | undefined;
|
|
156
|
+
} | undefined;
|
|
157
|
+
}, {
|
|
158
|
+
testType: TestType;
|
|
159
|
+
fileName: string;
|
|
160
|
+
endpoint: string;
|
|
161
|
+
testId: string;
|
|
162
|
+
reasoning: string;
|
|
163
|
+
description?: string | undefined;
|
|
164
|
+
category?: unknown;
|
|
165
|
+
traceFile?: string | undefined;
|
|
166
|
+
scenarioFile?: string | undefined;
|
|
167
|
+
frontendTrace?: string | undefined;
|
|
168
|
+
targetElements?: {
|
|
169
|
+
role: string;
|
|
170
|
+
accessibleName: string;
|
|
171
|
+
testId: string | null;
|
|
172
|
+
stableId: string | null;
|
|
173
|
+
contextText: string[] | null;
|
|
174
|
+
mutability?: "unknown" | "mutable" | "immutable" | undefined;
|
|
175
|
+
widgetType?: "custom" | "unknown" | "native" | undefined;
|
|
176
|
+
}[] | null | undefined;
|
|
177
|
+
pageContext?: {
|
|
178
|
+
url: string;
|
|
179
|
+
pageHash?: string | undefined;
|
|
180
|
+
} | undefined;
|
|
181
|
+
}>;
|
|
182
|
+
export declare const additionalRecommendationSchema: z.ZodEffects<z.ZodObject<{
|
|
183
|
+
testId: z.ZodString;
|
|
184
|
+
testType: z.ZodNativeEnum<typeof TestType>;
|
|
185
|
+
category: z.ZodEffects<z.ZodEnum<["business_rule", "security_boundary", "data_integrity", "breaking_change", "auth", "error_handling", "workflow", "data_validation", "crud"]>, "breaking_change" | "business_rule" | "security_boundary" | "data_integrity" | "auth" | "error_handling" | "workflow" | "data_validation" | "crud", unknown>;
|
|
186
|
+
primaryEndpoint: z.ZodOptional<z.ZodString>;
|
|
187
|
+
scenarioName: z.ZodOptional<z.ZodString>;
|
|
188
|
+
steps: z.ZodArray<z.ZodObject<{
|
|
189
|
+
method: z.ZodOptional<z.ZodNativeEnum<typeof HttpMethod>>;
|
|
190
|
+
path: z.ZodOptional<z.ZodString>;
|
|
191
|
+
description: z.ZodString;
|
|
192
|
+
expectedStatusCode: z.ZodOptional<z.ZodNumber>;
|
|
193
|
+
requestBody: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
194
|
+
responseBody: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
195
|
+
}, "strip", z.ZodTypeAny, {
|
|
196
|
+
description: string;
|
|
197
|
+
path?: string | undefined;
|
|
198
|
+
method?: HttpMethod | undefined;
|
|
199
|
+
requestBody?: Record<string, any> | undefined;
|
|
200
|
+
responseBody?: Record<string, any> | undefined;
|
|
201
|
+
expectedStatusCode?: number | undefined;
|
|
202
|
+
}, {
|
|
203
|
+
description: string;
|
|
204
|
+
path?: string | undefined;
|
|
205
|
+
method?: HttpMethod | undefined;
|
|
206
|
+
requestBody?: Record<string, any> | undefined;
|
|
207
|
+
responseBody?: Record<string, any> | undefined;
|
|
208
|
+
expectedStatusCode?: number | undefined;
|
|
209
|
+
}>, "many">;
|
|
210
|
+
description: z.ZodString;
|
|
211
|
+
priority: z.ZodEffects<z.ZodEnum<["high", "medium", "low"]>, "high" | "medium" | "low", unknown>;
|
|
212
|
+
openApiSpec: z.ZodOptional<z.ZodString>;
|
|
213
|
+
backendTrace: z.ZodOptional<z.ZodString>;
|
|
214
|
+
frontendTrace: z.ZodOptional<z.ZodString>;
|
|
215
|
+
reasoning: z.ZodString;
|
|
216
|
+
targetElements: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
217
|
+
role: z.ZodString;
|
|
218
|
+
accessibleName: z.ZodString;
|
|
219
|
+
testId: z.ZodNullable<z.ZodString>;
|
|
220
|
+
stableId: z.ZodNullable<z.ZodString>;
|
|
221
|
+
contextText: z.ZodNullable<z.ZodArray<z.ZodString, "many">>;
|
|
222
|
+
mutability: z.ZodOptional<z.ZodEnum<["mutable", "immutable", "unknown"]>>;
|
|
223
|
+
widgetType: z.ZodOptional<z.ZodEnum<["native", "custom", "unknown"]>>;
|
|
224
|
+
}, "strip", z.ZodTypeAny, {
|
|
225
|
+
role: string;
|
|
226
|
+
accessibleName: string;
|
|
227
|
+
testId: string | null;
|
|
228
|
+
stableId: string | null;
|
|
229
|
+
contextText: string[] | null;
|
|
230
|
+
mutability?: "unknown" | "mutable" | "immutable" | undefined;
|
|
231
|
+
widgetType?: "custom" | "unknown" | "native" | undefined;
|
|
232
|
+
}, {
|
|
233
|
+
role: string;
|
|
234
|
+
accessibleName: string;
|
|
235
|
+
testId: string | null;
|
|
236
|
+
stableId: string | null;
|
|
237
|
+
contextText: string[] | null;
|
|
238
|
+
mutability?: "unknown" | "mutable" | "immutable" | undefined;
|
|
239
|
+
widgetType?: "custom" | "unknown" | "native" | undefined;
|
|
240
|
+
}>, "many">>>;
|
|
241
|
+
pageContext: z.ZodOptional<z.ZodObject<{
|
|
242
|
+
url: z.ZodString;
|
|
243
|
+
pageHash: z.ZodOptional<z.ZodString>;
|
|
244
|
+
}, "strip", z.ZodTypeAny, {
|
|
245
|
+
url: string;
|
|
246
|
+
pageHash?: string | undefined;
|
|
247
|
+
}, {
|
|
248
|
+
url: string;
|
|
249
|
+
pageHash?: string | undefined;
|
|
250
|
+
}>>;
|
|
251
|
+
}, "strip", z.ZodTypeAny, {
|
|
252
|
+
description: string;
|
|
253
|
+
priority: "high" | "medium" | "low";
|
|
254
|
+
testType: TestType;
|
|
255
|
+
category: "breaking_change" | "business_rule" | "security_boundary" | "data_integrity" | "auth" | "error_handling" | "workflow" | "data_validation" | "crud";
|
|
256
|
+
steps: {
|
|
257
|
+
description: string;
|
|
258
|
+
path?: string | undefined;
|
|
259
|
+
method?: HttpMethod | undefined;
|
|
260
|
+
requestBody?: Record<string, any> | undefined;
|
|
261
|
+
responseBody?: Record<string, any> | undefined;
|
|
262
|
+
expectedStatusCode?: number | undefined;
|
|
263
|
+
}[];
|
|
264
|
+
testId: string;
|
|
265
|
+
reasoning: string;
|
|
266
|
+
scenarioName?: string | undefined;
|
|
267
|
+
frontendTrace?: string | undefined;
|
|
268
|
+
targetElements?: {
|
|
269
|
+
role: string;
|
|
270
|
+
accessibleName: string;
|
|
271
|
+
testId: string | null;
|
|
272
|
+
stableId: string | null;
|
|
273
|
+
contextText: string[] | null;
|
|
274
|
+
mutability?: "unknown" | "mutable" | "immutable" | undefined;
|
|
275
|
+
widgetType?: "custom" | "unknown" | "native" | undefined;
|
|
276
|
+
}[] | null | undefined;
|
|
277
|
+
pageContext?: {
|
|
278
|
+
url: string;
|
|
279
|
+
pageHash?: string | undefined;
|
|
280
|
+
} | undefined;
|
|
281
|
+
primaryEndpoint?: string | undefined;
|
|
282
|
+
openApiSpec?: string | undefined;
|
|
283
|
+
backendTrace?: string | undefined;
|
|
284
|
+
}, {
|
|
285
|
+
description: string;
|
|
286
|
+
testType: TestType;
|
|
287
|
+
steps: {
|
|
288
|
+
description: string;
|
|
289
|
+
path?: string | undefined;
|
|
290
|
+
method?: HttpMethod | undefined;
|
|
291
|
+
requestBody?: Record<string, any> | undefined;
|
|
292
|
+
responseBody?: Record<string, any> | undefined;
|
|
293
|
+
expectedStatusCode?: number | undefined;
|
|
294
|
+
}[];
|
|
295
|
+
testId: string;
|
|
296
|
+
reasoning: string;
|
|
297
|
+
priority?: unknown;
|
|
298
|
+
scenarioName?: string | undefined;
|
|
299
|
+
category?: unknown;
|
|
300
|
+
frontendTrace?: string | undefined;
|
|
301
|
+
targetElements?: {
|
|
302
|
+
role: string;
|
|
303
|
+
accessibleName: string;
|
|
304
|
+
testId: string | null;
|
|
305
|
+
stableId: string | null;
|
|
306
|
+
contextText: string[] | null;
|
|
307
|
+
mutability?: "unknown" | "mutable" | "immutable" | undefined;
|
|
308
|
+
widgetType?: "custom" | "unknown" | "native" | undefined;
|
|
309
|
+
}[] | null | undefined;
|
|
310
|
+
pageContext?: {
|
|
311
|
+
url: string;
|
|
312
|
+
pageHash?: string | undefined;
|
|
313
|
+
} | undefined;
|
|
314
|
+
primaryEndpoint?: string | undefined;
|
|
315
|
+
openApiSpec?: string | undefined;
|
|
316
|
+
backendTrace?: string | undefined;
|
|
317
|
+
}>, {
|
|
318
|
+
description: string;
|
|
319
|
+
priority: "high" | "medium" | "low";
|
|
320
|
+
testType: TestType;
|
|
321
|
+
category: "breaking_change" | "business_rule" | "security_boundary" | "data_integrity" | "auth" | "error_handling" | "workflow" | "data_validation" | "crud";
|
|
322
|
+
steps: {
|
|
323
|
+
description: string;
|
|
324
|
+
path?: string | undefined;
|
|
325
|
+
method?: HttpMethod | undefined;
|
|
326
|
+
requestBody?: Record<string, any> | undefined;
|
|
327
|
+
responseBody?: Record<string, any> | undefined;
|
|
328
|
+
expectedStatusCode?: number | undefined;
|
|
329
|
+
}[];
|
|
330
|
+
testId: string;
|
|
331
|
+
reasoning: string;
|
|
332
|
+
scenarioName?: string | undefined;
|
|
333
|
+
frontendTrace?: string | undefined;
|
|
334
|
+
targetElements?: {
|
|
335
|
+
role: string;
|
|
336
|
+
accessibleName: string;
|
|
337
|
+
testId: string | null;
|
|
338
|
+
stableId: string | null;
|
|
339
|
+
contextText: string[] | null;
|
|
340
|
+
mutability?: "unknown" | "mutable" | "immutable" | undefined;
|
|
341
|
+
widgetType?: "custom" | "unknown" | "native" | undefined;
|
|
342
|
+
}[] | null | undefined;
|
|
343
|
+
pageContext?: {
|
|
344
|
+
url: string;
|
|
345
|
+
pageHash?: string | undefined;
|
|
346
|
+
} | undefined;
|
|
347
|
+
primaryEndpoint?: string | undefined;
|
|
348
|
+
openApiSpec?: string | undefined;
|
|
349
|
+
backendTrace?: string | undefined;
|
|
350
|
+
}, {
|
|
351
|
+
description: string;
|
|
352
|
+
testType: TestType;
|
|
353
|
+
steps: {
|
|
354
|
+
description: string;
|
|
355
|
+
path?: string | undefined;
|
|
356
|
+
method?: HttpMethod | undefined;
|
|
357
|
+
requestBody?: Record<string, any> | undefined;
|
|
358
|
+
responseBody?: Record<string, any> | undefined;
|
|
359
|
+
expectedStatusCode?: number | undefined;
|
|
360
|
+
}[];
|
|
361
|
+
testId: string;
|
|
362
|
+
reasoning: string;
|
|
363
|
+
priority?: unknown;
|
|
364
|
+
scenarioName?: string | undefined;
|
|
365
|
+
category?: unknown;
|
|
366
|
+
frontendTrace?: string | undefined;
|
|
367
|
+
targetElements?: {
|
|
368
|
+
role: string;
|
|
369
|
+
accessibleName: string;
|
|
370
|
+
testId: string | null;
|
|
371
|
+
stableId: string | null;
|
|
372
|
+
contextText: string[] | null;
|
|
373
|
+
mutability?: "unknown" | "mutable" | "immutable" | undefined;
|
|
374
|
+
widgetType?: "custom" | "unknown" | "native" | undefined;
|
|
375
|
+
}[] | null | undefined;
|
|
376
|
+
pageContext?: {
|
|
377
|
+
url: string;
|
|
378
|
+
pageHash?: string | undefined;
|
|
379
|
+
} | undefined;
|
|
380
|
+
primaryEndpoint?: string | undefined;
|
|
381
|
+
openApiSpec?: string | undefined;
|
|
382
|
+
backendTrace?: string | undefined;
|
|
383
|
+
}>;
|
|
384
|
+
export declare function registerSubmitReportTool(server: McpServer): void;
|
|
@@ -22,11 +22,35 @@ const testResultSchema = z.object({
|
|
|
22
22
|
status: z.enum(["Pass", "Fail", "Skipped"]).describe("Test execution result"),
|
|
23
23
|
details: z.string().describe("One sentence — no embedded newlines, no markdown. e.g. '10.8s, products_contract_test.py' or 'failed: <one-line error summary>, products_contract_test.py'"),
|
|
24
24
|
});
|
|
25
|
+
// Structured grounding for UI recommendations. Lifted verbatim from a
|
|
26
|
+
// `browser_blueprint` element captured during this run. Source of truth for
|
|
27
|
+
// codegen (prefers testId > stableId > role+name for locator selection),
|
|
28
|
+
// the verifier (cross-checks each field against captured blueprints), and
|
|
29
|
+
// any future tooling that wants reliable grounding data without prose
|
|
30
|
+
// parsing. `reasoning` is free-form prose constrained by the Blueprint
|
|
31
|
+
// Citation Invariant — every element cited must appear in `targetElements`.
|
|
32
|
+
// See testbot prompt step 4 for the full populate-and-render rules.
|
|
33
|
+
export const targetElementSchema = z.object({
|
|
34
|
+
role: z.string().describe("ARIA role (e.g. 'button', 'heading', 'textbox', 'link'). Lifted verbatim from the captured blueprint element's `role` field."),
|
|
35
|
+
accessibleName: z.string().describe("Computed accessible name (e.g. 'Save changes', 'Order Details'). Lifted verbatim from the captured blueprint element's `accessibleName` field. Must match the bolded name in `reasoning` character-for-character."),
|
|
36
|
+
testId: z.string().nullable().describe("data-testid attribute value (preferred locator handle), or null when the element has no data-testid. Lifted from the blueprint element's `testId`."),
|
|
37
|
+
stableId: z.string().nullable().describe("Unique HTML id attribute value (fallback locator when no testId), or null. Lifted from the blueprint element's `stableId`."),
|
|
38
|
+
contextText: z.array(z.string()).nullable().describe("Disambiguating row text for elements inside repeating sections (table rows, list items): the row's surrounding non-interactive text. Lifted from the blueprint repeatingElement's items[].contextText. null for non-repeating elements."),
|
|
39
|
+
mutability: z.enum(["mutable", "immutable", "unknown"]).optional().describe("Whether the element's content/state is expected to change between captures. 'mutable' elements are behavioral-test targets; 'immutable' are smoke-test targets. Copied from the blueprint element's `mutability`."),
|
|
40
|
+
widgetType: z.enum(["native", "custom", "unknown"]).optional().describe("'native' = HTML built-ins (button, input). 'custom' or 'unknown' = non-standard composites; fall back to snapshot-driven trial clicks for interaction. Copied from the blueprint element's `widgetType`."),
|
|
41
|
+
});
|
|
42
|
+
// Page metadata for a UI recommendation. Lifted from the BlueprintCapture
|
|
43
|
+
// the agent used to populate `targetElements`. Codegen reads `url` to drive
|
|
44
|
+
// page.goto(); the verifier uses `pageHash` to detect stale captures.
|
|
45
|
+
export const pageContextSchema = z.object({
|
|
46
|
+
url: z.string().describe("URL of the page where the test runs. Lifted from BlueprintCapture.url."),
|
|
47
|
+
pageHash: z.string().optional().describe("Opaque hash of the captured page state (BlueprintCapture.pageHash). Lets the verifier confirm the recommendation was grounded in a still-current capture."),
|
|
48
|
+
});
|
|
25
49
|
// TODO: Unify newTestSchema and additionalRecommendationSchema into a single
|
|
26
50
|
// interface that adds an `implemented: boolean` field. Both describe the same
|
|
27
51
|
// concept (a test recommendation) — the only difference is whether it was
|
|
28
52
|
// generated in this run or left for later. Tracked per Archit's review comment.
|
|
29
|
-
const newTestSchema = z.object({
|
|
53
|
+
export const newTestSchema = z.object({
|
|
30
54
|
testId: z.string().describe("Human-readable kebab-case identifier, e.g. 'contract-get-products' or 'integration-users-orders-workflow'. Format: '<testType>-<method>-<resource>' for single-endpoint tests or '<testType>-<scenario-slug>' for multi-step tests. Must be unique within the report."),
|
|
31
55
|
testType: z.nativeEnum(TestType).describe("Type of test created. Do not include priority or other metadata in this field."),
|
|
32
56
|
category: z.preprocess((val) => externalCategory(val), z.enum(TEST_CATEGORIES)).describe("Test category — critical categories (security_boundary, business_rule, data_integrity, breaking_change) get generation priority over workflow"),
|
|
@@ -37,6 +61,71 @@ const newTestSchema = z.object({
|
|
|
37
61
|
traceFile: z.string().optional().describe("Path to the backend trace file if used or created"),
|
|
38
62
|
frontendTrace: z.string().optional().describe("Path to the Playwright/UI trace file if used or created"),
|
|
39
63
|
reasoning: z.string().describe("Why this test was created: what production risk it mitigates, what code pattern it targets, or what coverage gap it fills"),
|
|
64
|
+
targetElements: z.array(targetElementSchema).min(1).nullable().optional().describe("UI tests only: structured grounding for one or more elements the test targets. Most tests target a single element (array length 1); render-state and multi-step UI tests target several (array length 2+). Each entry must be lifted verbatim from a captured blueprint element. Set to null when blueprint capture failed (also requires '[no-blueprint-data]' marker in BOTH description and reasoning). See Blueprint Citation Invariant in testbot prompt."),
|
|
65
|
+
pageContext: pageContextSchema.optional().describe("UI tests only: page metadata for the test. Lifted from the BlueprintCapture used during grounding."),
|
|
66
|
+
}).superRefine((rec, ctx) => {
|
|
67
|
+
// targetElements / pageContext are UI-only.
|
|
68
|
+
if (rec.testType !== TestType.UI) {
|
|
69
|
+
for (const field of ["targetElements", "pageContext"]) {
|
|
70
|
+
if (rec[field] !== undefined) {
|
|
71
|
+
ctx.addIssue({
|
|
72
|
+
code: z.ZodIssueCode.custom,
|
|
73
|
+
path: [field],
|
|
74
|
+
message: `${field} is only valid for testType: 'ui'`,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
// description is required for UI tests (walkthrough of steps/assertions).
|
|
81
|
+
if (!rec.description) {
|
|
82
|
+
ctx.addIssue({
|
|
83
|
+
code: z.ZodIssueCode.custom,
|
|
84
|
+
path: ["description"],
|
|
85
|
+
message: "description is required for testType: 'ui'.",
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
// targetElements must be present (array or null — not omitted entirely).
|
|
89
|
+
if (rec.targetElements === undefined) {
|
|
90
|
+
ctx.addIssue({
|
|
91
|
+
code: z.ZodIssueCode.custom,
|
|
92
|
+
path: ["targetElements"],
|
|
93
|
+
message: "targetElements is required for testType: 'ui'. Use null when blueprint capture failed (and add '[no-blueprint-data]' to both description and reasoning).",
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
// pageContext is required when targetElements is an array (grounded), forbidden when null.
|
|
97
|
+
if (Array.isArray(rec.targetElements) && rec.pageContext === undefined) {
|
|
98
|
+
ctx.addIssue({
|
|
99
|
+
code: z.ZodIssueCode.custom,
|
|
100
|
+
path: ["pageContext"],
|
|
101
|
+
message: "pageContext is required for testType: 'ui' when targetElements is an array.",
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
if (rec.targetElements === null && rec.pageContext !== undefined) {
|
|
105
|
+
ctx.addIssue({
|
|
106
|
+
code: z.ZodIssueCode.custom,
|
|
107
|
+
path: ["pageContext"],
|
|
108
|
+
message: "pageContext must be omitted when targetElements is null (no blueprint data).",
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
// When targetElements is null, both description and reasoning must carry the '[no-blueprint-data]' marker.
|
|
112
|
+
if (rec.targetElements === null) {
|
|
113
|
+
if (!rec.reasoning.includes("[no-blueprint-data]")) {
|
|
114
|
+
ctx.addIssue({
|
|
115
|
+
code: z.ZodIssueCode.custom,
|
|
116
|
+
path: ["reasoning"],
|
|
117
|
+
message: "reasoning must contain '[no-blueprint-data]' when targetElements is null.",
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
if (rec.description && !rec.description.includes("[no-blueprint-data]")) {
|
|
121
|
+
ctx.addIssue({
|
|
122
|
+
code: z.ZodIssueCode.custom,
|
|
123
|
+
path: ["description"],
|
|
124
|
+
message: "description must contain '[no-blueprint-data]' when targetElements is null.",
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
40
129
|
});
|
|
41
130
|
const descriptionSchema = z.object({
|
|
42
131
|
description: z.string().describe("One-line description. Do NOT prefix with the severity level — severity is a separate field. Include code logic bugs from the diff, test generation/execution failures, and environment misconfiguration."),
|
|
@@ -63,12 +152,14 @@ export const additionalRecommendationSchema = z.object({
|
|
|
63
152
|
scenarioName: z.string().optional().describe("Proposed scenario name for future generation, e.g. 'products-orders-workflow'. No file exists yet — this is a suggestion only. Omit if not applicable."),
|
|
64
153
|
// TODO: replace text with max(3) and check for regression
|
|
65
154
|
steps: z.array(scenarioStepSchema).describe("Ordered sequence of API/UI steps in this test scenario (at most 3). Each step must include method and path so the endpoints are explicit. Omit requestBody and responseBody from steps."),
|
|
66
|
-
description: z.string().describe("
|
|
155
|
+
description: z.string().describe("Walkthrough of what the test does — the steps and assertions. For multi-step scenarios, list the endpoints involved. The 'why it is valuable' belongs in reasoning."),
|
|
67
156
|
priority: z.preprocess((val) => (typeof val === "string" ? val.toLowerCase() : val), z.enum(["high", "medium", "low"])).describe("Priority level: high, medium, or low. First check diff relevance — does the test target an endpoint changed in this PR? HIGH: diff-relevant security/auth/error tests, cross-resource isolation for diff endpoints, CRUD lifecycle for NEW endpoints in the diff. MEDIUM: diff-relevant business-rule happy paths, multi-resource workflows involving diff endpoints, security/error tests for NON-diff endpoints. LOW: tests targeting only unchanged endpoints, trivially discoverable happy paths duplicating generated tests."),
|
|
68
157
|
openApiSpec: z.string().optional().describe("Path to OpenAPI/Swagger spec file if available, e.g. 'openapi.yaml'"),
|
|
69
158
|
backendTrace: z.string().optional().describe("Path to backend trace file if available, e.g. 'tests/skyramp-traces.json'. Used by integration and E2E tests."),
|
|
70
159
|
frontendTrace: z.string().optional().describe("Path to Playwright/UI trace file if available, e.g. 'tests/skyramp-playwright.zip'. UI tests need this; E2E tests need both frontend and backend traces."),
|
|
71
160
|
reasoning: z.string().describe("Why this test is recommended: the specific production risk, business rule, or security boundary it would validate"),
|
|
161
|
+
targetElements: z.array(targetElementSchema).min(1).nullable().optional().describe("UI tests only: structured grounding for one or more elements the test targets. Most tests target a single element (array length 1); render-state and multi-step UI tests target several (array length 2+). Each entry must be lifted verbatim from a captured blueprint element. Set to null when blueprint capture failed (also requires '[no-blueprint-data]' marker in BOTH description and reasoning). See Blueprint Citation Invariant in testbot prompt."),
|
|
162
|
+
pageContext: pageContextSchema.optional().describe("UI tests only: page metadata for the test. Lifted from the BlueprintCapture used during grounding."),
|
|
72
163
|
}).superRefine((rec, ctx) => {
|
|
73
164
|
if (rec.testType === TestType.CONTRACT && !rec.primaryEndpoint) {
|
|
74
165
|
ctx.addIssue({
|
|
@@ -77,6 +168,57 @@ export const additionalRecommendationSchema = z.object({
|
|
|
77
168
|
message: "primaryEndpoint is required for contract tests — provide the HTTP verb and path, e.g. 'PATCH /api/v1/orders/{order_id}'.",
|
|
78
169
|
});
|
|
79
170
|
}
|
|
171
|
+
// targetElements / pageContext are UI-only.
|
|
172
|
+
if (rec.testType !== TestType.UI) {
|
|
173
|
+
for (const field of ["targetElements", "pageContext"]) {
|
|
174
|
+
if (rec[field] !== undefined) {
|
|
175
|
+
ctx.addIssue({
|
|
176
|
+
code: z.ZodIssueCode.custom,
|
|
177
|
+
path: [field],
|
|
178
|
+
message: `${field} is only valid for testType: 'ui'`,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
if (rec.targetElements === undefined) {
|
|
185
|
+
ctx.addIssue({
|
|
186
|
+
code: z.ZodIssueCode.custom,
|
|
187
|
+
path: ["targetElements"],
|
|
188
|
+
message: "targetElements is required for testType: 'ui'. Use null when blueprint capture failed (and add '[no-blueprint-data]' to both description and reasoning).",
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
if (Array.isArray(rec.targetElements) && rec.pageContext === undefined) {
|
|
192
|
+
ctx.addIssue({
|
|
193
|
+
code: z.ZodIssueCode.custom,
|
|
194
|
+
path: ["pageContext"],
|
|
195
|
+
message: "pageContext is required for testType: 'ui' when targetElements is an array.",
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
if (rec.targetElements === null && rec.pageContext !== undefined) {
|
|
199
|
+
ctx.addIssue({
|
|
200
|
+
code: z.ZodIssueCode.custom,
|
|
201
|
+
path: ["pageContext"],
|
|
202
|
+
message: "pageContext must be omitted when targetElements is null (no blueprint data).",
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
if (rec.targetElements === null) {
|
|
206
|
+
if (!rec.reasoning.includes("[no-blueprint-data]")) {
|
|
207
|
+
ctx.addIssue({
|
|
208
|
+
code: z.ZodIssueCode.custom,
|
|
209
|
+
path: ["reasoning"],
|
|
210
|
+
message: "reasoning must contain '[no-blueprint-data]' when targetElements is null.",
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
if (!rec.description.includes("[no-blueprint-data]")) {
|
|
214
|
+
ctx.addIssue({
|
|
215
|
+
code: z.ZodIssueCode.custom,
|
|
216
|
+
path: ["description"],
|
|
217
|
+
message: "description must contain '[no-blueprint-data]' when targetElements is null.",
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
80
222
|
});
|
|
81
223
|
const testMaintenanceSchema = z.object({
|
|
82
224
|
testType: z.nativeEnum(TestType).describe("Type of test."),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|