@skyramp/mcp 0.1.8 → 0.2.0-rc.2
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/index.js +4 -2
- package/build/playwright/registerPlaywrightTools.js +12 -0
- package/build/playwright/traceRecordingPrompt.js +15 -0
- package/build/prompts/code-reuse.js +106 -7
- package/build/prompts/pom-aware-code-reuse.js +106 -7
- package/build/prompts/startTraceCollectionPrompts.js +37 -15
- package/build/prompts/test-maintenance/drift-analysis-prompt.js +26 -31
- package/build/prompts/test-maintenance/drift-analysis-prompt.test.js +40 -1
- package/build/prompts/test-maintenance/driftAnalysisSections.js +90 -86
- package/build/prompts/test-recommendation/analysisOutputPrompt.js +286 -163
- package/build/prompts/test-recommendation/analysisOutputPrompt.test.js +154 -45
- package/build/prompts/test-recommendation/diffExecutionPlan.js +246 -117
- package/build/prompts/test-recommendation/promptPlan.js +290 -0
- package/build/prompts/test-recommendation/promptPlan.test.js +336 -0
- package/build/prompts/test-recommendation/recommendationSections.js +4 -3
- package/build/prompts/test-recommendation/recommendationShared.js +23 -1
- package/build/prompts/test-recommendation/scopeAssessment.js +65 -14
- package/build/prompts/test-recommendation/scopeAssessment.test.js +93 -2
- package/build/prompts/test-recommendation/test-recommendation-prompt.js +36 -12
- package/build/prompts/test-recommendation/test-recommendation-prompt.test.js +316 -1
- package/build/prompts/testbot/testbot-prompts.js +73 -13
- package/build/prompts/testbot/testbot-prompts.test.js +114 -1
- package/build/resources/testbotResource.js +1 -1
- package/build/services/ScenarioGenerationService.integration.test.js +158 -0
- package/build/services/ScenarioGenerationService.js +47 -4
- package/build/services/ScenarioGenerationService.test.js +158 -22
- package/build/services/TestExecutionService.js +73 -15
- package/build/services/TestExecutionService.test.js +105 -0
- package/build/services/TestGenerationService.js +11 -1
- package/build/tools/executeSkyrampTestTool.js +1 -10
- package/build/tools/generate-tests/generateBatchScenarioRestTool.js +16 -4
- package/build/tools/generate-tests/generateIntegrationRestTool.js +2 -0
- package/build/tools/generate-tests/generateUIRestTool.js +2 -0
- package/build/tools/test-management/actionsTool.js +152 -63
- package/build/tools/test-management/analyzeChangesTool.js +178 -64
- package/build/tools/test-management/analyzeChangesTool.test.js +103 -16
- package/build/tools/test-management/analyzeTestHealthTool.js +30 -81
- package/build/tools/test-management/index.js +1 -0
- package/build/tools/test-management/uiAnalyzeChangesTool.js +149 -0
- package/build/tools/test-management/uiAnalyzeChangesTool.test.js +100 -0
- package/build/tools/trace/resolveSaveStoragePath.js +16 -0
- package/build/tools/trace/resolveSaveStoragePath.test.js +17 -0
- package/build/tools/trace/resolveSessionPaths.js +39 -0
- package/build/tools/trace/resolveSessionPaths.test.js +103 -0
- package/build/tools/trace/sessionState.js +14 -0
- package/build/tools/trace/sessionState.test.js +17 -0
- package/build/tools/trace/startTraceCollectionTool.js +84 -14
- package/build/tools/trace/stopTraceCollectionTool.js +9 -2
- package/build/types/TestAnalysis.js +50 -0
- package/build/types/TestRecommendation.js +6 -58
- package/build/types/TestTypes.js +1 -1
- package/build/utils/AnalysisStateManager.js +22 -11
- package/build/utils/branchDiff.js +11 -2
- package/build/utils/docker.test.js +1 -1
- package/build/utils/gitStaging.js +52 -3
- package/build/utils/gitStaging.test.js +19 -1
- package/build/utils/repoScanner.js +18 -10
- package/build/utils/repoScanner.test.js +92 -0
- package/build/utils/routeParsers.js +180 -25
- package/build/utils/routeParsers.test.js +180 -1
- package/build/utils/scenarioDrafting.js +220 -17
- package/build/utils/scenarioDrafting.test.js +182 -9
- package/build/utils/sourceRouteExtractor.js +806 -0
- package/build/utils/sourceRouteExtractor.test.js +565 -0
- package/build/utils/uiPageEnumerator.js +319 -0
- package/build/utils/uiPageEnumerator.test.js +422 -0
- package/build/utils/utils.js +27 -0
- package/build/utils/versions.js +1 -1
- package/build/utils/workspaceAuth.js +33 -4
- package/node_modules/playwright/ThirdPartyNotices.txt +6 -6
- package/node_modules/playwright/lib/dom-analyzer/analyze.js +111 -0
- package/node_modules/playwright/lib/dom-analyzer/blueprint.js +1210 -0
- package/node_modules/playwright/lib/dom-analyzer/blueprint.test.js +396 -0
- package/node_modules/playwright/lib/dom-analyzer/blueprintCache.js +57 -0
- package/node_modules/playwright/lib/dom-analyzer/blueprintCache.test.js +57 -0
- package/node_modules/playwright/lib/dom-analyzer/blueprintDiff.js +254 -0
- package/node_modules/playwright/lib/dom-analyzer/blueprintDiff.test.js +304 -0
- package/node_modules/playwright/lib/dom-analyzer/crawler.js +384 -0
- package/node_modules/playwright/lib/dom-analyzer/curatedWidgets.js +73 -0
- package/node_modules/playwright/lib/dom-analyzer/dynamicId.js +43 -0
- package/node_modules/playwright/lib/dom-analyzer/dynamicId.test.js +85 -0
- package/node_modules/playwright/lib/dom-analyzer/fingerprint.js +90 -0
- package/node_modules/playwright/lib/dom-analyzer/fingerprint.test.js +231 -0
- package/node_modules/playwright/lib/dom-analyzer/fingerprintAblation.fixtures.js +145 -0
- package/node_modules/playwright/lib/dom-analyzer/fingerprintAblation.test.js +41 -0
- package/node_modules/playwright/lib/dom-analyzer/graph.js +36 -0
- package/node_modules/playwright/lib/dom-analyzer/liveFingerprints.js +43 -0
- package/node_modules/playwright/lib/dom-analyzer/logicalNameResolver.js +72 -0
- package/node_modules/playwright/lib/dom-analyzer/logicalNameResolver.test.js +182 -0
- package/node_modules/playwright/lib/dom-analyzer/possibleAssertions.js +150 -0
- package/node_modules/playwright/lib/dom-analyzer/possibleAssertions.test.js +470 -0
- package/node_modules/playwright/lib/dom-analyzer/sectionGrouper.js +169 -0
- package/node_modules/playwright/lib/dom-analyzer/sectionGrouper.test.js +269 -0
- package/node_modules/playwright/lib/dom-analyzer/serialization.js +75 -0
- package/node_modules/playwright/lib/dom-analyzer/slug.js +30 -0
- package/node_modules/playwright/lib/dom-analyzer/slug.test.js +84 -0
- package/node_modules/playwright/lib/dom-analyzer/widgetContract.js +127 -0
- package/node_modules/playwright/lib/dom-analyzer/widgetContract.test.js +212 -0
- package/node_modules/playwright/lib/mcp/browser/browserContextFactory.js +3 -1
- package/node_modules/playwright/lib/mcp/browser/config.js +1 -1
- package/node_modules/playwright/lib/mcp/browser/context.js +17 -1
- package/node_modules/playwright/lib/mcp/browser/tab.js +38 -0
- package/node_modules/playwright/lib/mcp/browser/tools/domAnalyzer.js +261 -0
- package/node_modules/playwright/lib/mcp/browser/tools/keyboard.js +3 -3
- package/node_modules/playwright/lib/mcp/browser/tools/pageBlueprint.js +146 -0
- package/node_modules/playwright/lib/mcp/browser/tools/pageBlueprint.test.js +140 -0
- package/node_modules/playwright/lib/mcp/browser/tools/sitemap.js +226 -0
- package/node_modules/playwright/lib/mcp/browser/tools/snapshot.js +2 -2
- package/node_modules/playwright/lib/mcp/browser/tools/widgetContract.js +168 -0
- package/node_modules/playwright/lib/mcp/browser/tools.js +6 -0
- package/node_modules/playwright/lib/mcp/skyramp/traceRecordingBackend.js +52 -12
- package/node_modules/playwright/lib/mcp/test/skyRampExport.js +64 -13
- package/node_modules/playwright/package.json +1 -1
- package/node_modules/playwright/skyramp-playwright-1.58.2-skyramp.8.9.3.tgz +0 -0
- package/node_modules/playwright/skyramp-playwright-1.58.2-skyramp.8.9.4.tgz +0 -0
- package/node_modules/playwright/skyramp-playwright-1.58.2-skyramp.8.9.5.tgz +0 -0
- package/node_modules/playwright/skyramp-playwright-1.58.2-skyramp.8.9.6.tgz +0 -0
- package/package.json +3 -3
- package/build/services/TestHealthService.js +0 -694
- package/build/services/TestHealthService.test.js +0 -241
- package/build/types/TestDriftAnalysis.js +0 -1
- package/build/types/TestHealth.js +0 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
jest.mock("@skyramp/skyramp", () => ({
|
|
2
2
|
WorkspaceConfigManager: { create: jest.fn() },
|
|
3
3
|
}));
|
|
4
|
-
import { buildAnalysisOutputText } from "./analysisOutputPrompt.js";
|
|
4
|
+
import { buildAnalysisOutputText, getStepTraceCallers, ANALYSIS_STEP_READ_FILES, ANALYSIS_STEP_RESOLVE_PATHS, ANALYSIS_STEP_EXTRACT, ANALYSIS_STEP_DRAFT, ANALYSIS_STEP_CALL_TOOL, } from "./analysisOutputPrompt.js";
|
|
5
5
|
import { AnalysisScope } from "../../types/RepositoryAnalysis.js";
|
|
6
6
|
// ---------------------------------------------------------------------------
|
|
7
7
|
// Minimal fixture factory
|
|
@@ -26,10 +26,62 @@ function baseParams(overrides = {}) {
|
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
// ---------------------------------------------------------------------------
|
|
29
|
-
//
|
|
29
|
+
// Static step label constants
|
|
30
30
|
// ---------------------------------------------------------------------------
|
|
31
|
-
describe("
|
|
32
|
-
it("
|
|
31
|
+
describe("analysisOutputPrompt — static step label constants", () => {
|
|
32
|
+
it("exports sequential main-step labels", () => {
|
|
33
|
+
expect(ANALYSIS_STEP_READ_FILES).toBe("1");
|
|
34
|
+
expect(ANALYSIS_STEP_EXTRACT).toBe("2");
|
|
35
|
+
expect(ANALYSIS_STEP_DRAFT).toBe("3");
|
|
36
|
+
expect(ANALYSIS_STEP_CALL_TOOL).toBe("4");
|
|
37
|
+
});
|
|
38
|
+
it("exports sequential sub-step label for RESOLVE_PATHS", () => {
|
|
39
|
+
expect(ANALYSIS_STEP_RESOLVE_PATHS).toBe("1.1");
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
// getStepTraceCallers() — dynamic label for the conditional sub-step
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
describe("getStepTraceCallers()", () => {
|
|
46
|
+
it("returns '2.1' when non-frontend unmatched backend files are present in diff scope", () => {
|
|
47
|
+
const params = baseParams({
|
|
48
|
+
unmatchedFiles: ["server/helpers/DataUtils.java"],
|
|
49
|
+
});
|
|
50
|
+
expect(getStepTraceCallers(params)).toBe("2.1");
|
|
51
|
+
});
|
|
52
|
+
it("returns null when unmatchedFiles is empty", () => {
|
|
53
|
+
const params = baseParams({ unmatchedFiles: [] });
|
|
54
|
+
expect(getStepTraceCallers(params)).toBeNull();
|
|
55
|
+
});
|
|
56
|
+
it("returns null when unmatchedFiles is undefined", () => {
|
|
57
|
+
const params = baseParams({ unmatchedFiles: undefined });
|
|
58
|
+
expect(getStepTraceCallers(params)).toBeNull();
|
|
59
|
+
});
|
|
60
|
+
it("returns null when scope is full_repo even if unmatchedFiles is non-empty", () => {
|
|
61
|
+
const params = baseParams({
|
|
62
|
+
analysisScope: AnalysisScope.FullRepo,
|
|
63
|
+
unmatchedFiles: ["src/services/SomeService.ts"],
|
|
64
|
+
});
|
|
65
|
+
expect(getStepTraceCallers(params)).toBeNull();
|
|
66
|
+
});
|
|
67
|
+
it("returns null when unmatchedFiles contains only frontend component files", () => {
|
|
68
|
+
const params = baseParams({
|
|
69
|
+
unmatchedFiles: ["src/components/Button.tsx", "src/pages/Dashboard.jsx"],
|
|
70
|
+
});
|
|
71
|
+
expect(getStepTraceCallers(params)).toBeNull();
|
|
72
|
+
});
|
|
73
|
+
it("returns null when unmatchedFiles contains only non-code files", () => {
|
|
74
|
+
const params = baseParams({
|
|
75
|
+
unmatchedFiles: ["README.md", "package.json", "docker-compose.yml"],
|
|
76
|
+
});
|
|
77
|
+
expect(getStepTraceCallers(params)).toBeNull();
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
// Trace-callers sub-step output (Step 2.1)
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
describe("buildAnalysisOutputText — unmatchedFiles / trace-callers sub-step", () => {
|
|
84
|
+
it("includes the trace-callers block when unmatchedFiles is non-empty and scope is CurrentBranchDiff", () => {
|
|
33
85
|
const params = baseParams({
|
|
34
86
|
unmatchedFiles: [
|
|
35
87
|
"server/src/main/java/helpers/DataUtils.java",
|
|
@@ -37,12 +89,14 @@ describe("buildAnalysisOutputText — unmatchedFiles / Step 2.3 caller-tracing",
|
|
|
37
89
|
],
|
|
38
90
|
});
|
|
39
91
|
const output = buildAnalysisOutputText(params);
|
|
40
|
-
|
|
92
|
+
const label = getStepTraceCallers(params);
|
|
93
|
+
expect(label).not.toBeNull();
|
|
94
|
+
expect(output).toContain(`### Step ${label}: Trace callers of changed non-route files`);
|
|
41
95
|
expect(output).toContain("DataUtils.java");
|
|
42
96
|
expect(output).toContain("MustacheHelper.java");
|
|
43
97
|
expect(output).toContain("/execute");
|
|
44
98
|
});
|
|
45
|
-
it("lists each unmatched file as a bullet in the
|
|
99
|
+
it("lists each unmatched file as a bullet in the trace-callers block", () => {
|
|
46
100
|
const params = baseParams({
|
|
47
101
|
unmatchedFiles: ["src/services/OrderService.ts", "src/utils/pricingHelper.ts"],
|
|
48
102
|
});
|
|
@@ -50,46 +104,61 @@ describe("buildAnalysisOutputText — unmatchedFiles / Step 2.3 caller-tracing",
|
|
|
50
104
|
expect(output).toContain("- `src/services/OrderService.ts`");
|
|
51
105
|
expect(output).toContain("- `src/utils/pricingHelper.ts`");
|
|
52
106
|
});
|
|
53
|
-
it("omits
|
|
107
|
+
it("omits the trace-callers block when unmatchedFiles is empty", () => {
|
|
54
108
|
const params = baseParams({ unmatchedFiles: [] });
|
|
55
109
|
const output = buildAnalysisOutputText(params);
|
|
56
|
-
expect(
|
|
110
|
+
expect(getStepTraceCallers(params)).toBeNull();
|
|
57
111
|
expect(output).not.toContain("Trace callers of changed non-route files");
|
|
58
112
|
});
|
|
59
|
-
it("omits
|
|
113
|
+
it("omits the trace-callers block when unmatchedFiles is undefined", () => {
|
|
60
114
|
const params = baseParams({ unmatchedFiles: undefined });
|
|
61
115
|
const output = buildAnalysisOutputText(params);
|
|
62
|
-
expect(
|
|
116
|
+
expect(getStepTraceCallers(params)).toBeNull();
|
|
117
|
+
expect(output).not.toContain("Trace callers of changed non-route files");
|
|
63
118
|
});
|
|
64
|
-
it("omits
|
|
119
|
+
it("omits the trace-callers block when scope is full_repo even if unmatchedFiles is non-empty", () => {
|
|
65
120
|
const params = baseParams({
|
|
66
121
|
analysisScope: AnalysisScope.FullRepo,
|
|
67
122
|
unmatchedFiles: ["src/services/SomeService.ts"],
|
|
68
123
|
});
|
|
69
124
|
const output = buildAnalysisOutputText(params);
|
|
70
|
-
expect(
|
|
125
|
+
expect(getStepTraceCallers(params)).toBeNull();
|
|
126
|
+
expect(output).not.toContain("Trace callers of changed non-route files");
|
|
71
127
|
});
|
|
72
|
-
it("
|
|
128
|
+
it("trace-callers sub-step appears after the extract step in the output (phase 4b — no Step 2.5)", () => {
|
|
129
|
+
// This test uses no diff — falls back to the source-files branch.
|
|
73
130
|
const params = baseParams({
|
|
74
131
|
unmatchedFiles: ["src/utils/helper.ts"],
|
|
75
132
|
});
|
|
76
133
|
const output = buildAnalysisOutputText(params);
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
expect(
|
|
80
|
-
expect(
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
134
|
+
const label = getStepTraceCallers(params);
|
|
135
|
+
expect(label).not.toBeNull();
|
|
136
|
+
expect(output).toContain(`Step ${label}`);
|
|
137
|
+
expect(output).not.toContain("Step 2.5");
|
|
138
|
+
});
|
|
139
|
+
it("critical-patterns checklist is present in Step 2 regardless of diff availability (phase 4b)", () => {
|
|
140
|
+
// Step 2.5 was merged into Step 2 — patterns appear inline in ALL diff-scope branches.
|
|
141
|
+
const withDiff = baseParams({ unmatchedFiles: ["src/utils/foo.ts"], diffFilePath: "/tmp/pr.diff" });
|
|
142
|
+
const withDiffNoUnmatched = baseParams({ unmatchedFiles: [], diffFilePath: "/tmp/pr.diff" });
|
|
143
|
+
const noDiff = baseParams({ unmatchedFiles: [] });
|
|
144
|
+
const uiOnly = baseParams({
|
|
145
|
+
parsedDiff: {
|
|
146
|
+
changedFiles: ["src/components/Cart.tsx", "src/components/OrderList.vue"],
|
|
147
|
+
newEndpoints: [],
|
|
148
|
+
modifiedEndpoints: [],
|
|
149
|
+
},
|
|
150
|
+
unmatchedFiles: [],
|
|
151
|
+
});
|
|
152
|
+
expect(buildAnalysisOutputText(withDiff)).toContain("While reading, also note these patterns");
|
|
153
|
+
expect(buildAnalysisOutputText(withDiffNoUnmatched)).toContain("While reading, also note these patterns");
|
|
154
|
+
expect(buildAnalysisOutputText(noDiff)).toContain("While reading, also note these patterns");
|
|
155
|
+
expect(buildAnalysisOutputText(uiOnly)).toContain("While reading, also note these patterns");
|
|
156
|
+
// Step 2.5 header should never appear
|
|
157
|
+
expect(buildAnalysisOutputText(withDiff)).not.toContain("Step 2.5");
|
|
158
|
+
expect(buildAnalysisOutputText(noDiff)).not.toContain("Step 2.5");
|
|
159
|
+
expect(buildAnalysisOutputText(uiOnly)).not.toContain("Step 2.5");
|
|
160
|
+
});
|
|
161
|
+
it("omits trace-callers block when unmatchedFiles contains only frontend component files (UI-only PR)", () => {
|
|
93
162
|
const params = baseParams({
|
|
94
163
|
unmatchedFiles: [
|
|
95
164
|
"src/components/Button.tsx",
|
|
@@ -99,12 +168,10 @@ describe("buildAnalysisOutputText — unmatchedFiles / Step 2.3 caller-tracing",
|
|
|
99
168
|
],
|
|
100
169
|
});
|
|
101
170
|
const output = buildAnalysisOutputText(params);
|
|
102
|
-
expect(
|
|
171
|
+
expect(getStepTraceCallers(params)).toBeNull();
|
|
103
172
|
expect(output).not.toContain("Trace callers of changed non-route files");
|
|
104
173
|
});
|
|
105
|
-
it("omits
|
|
106
|
-
// README.md, package.json, etc. have no changed symbols to trace — listing them
|
|
107
|
-
// in Step 2.3 is misleading. (Copilot review fix)
|
|
174
|
+
it("omits trace-callers block when unmatchedFiles contains only non-code files (docs/config)", () => {
|
|
108
175
|
const params = baseParams({
|
|
109
176
|
unmatchedFiles: [
|
|
110
177
|
"README.md",
|
|
@@ -114,12 +181,12 @@ describe("buildAnalysisOutputText — unmatchedFiles / Step 2.3 caller-tracing",
|
|
|
114
181
|
],
|
|
115
182
|
});
|
|
116
183
|
const output = buildAnalysisOutputText(params);
|
|
117
|
-
expect(
|
|
184
|
+
expect(getStepTraceCallers(params)).toBeNull();
|
|
118
185
|
expect(output).not.toContain("Trace callers of changed non-route files");
|
|
119
186
|
});
|
|
120
|
-
it("emits
|
|
187
|
+
it("emits trace-callers for backend code files but excludes frontend/non-code siblings", () => {
|
|
121
188
|
// Mixed PR: one Java helper + one React component + one config file.
|
|
122
|
-
// Only the Java file should appear in the
|
|
189
|
+
// Only the Java file should appear in the trace-callers bullets.
|
|
123
190
|
const params = baseParams({
|
|
124
191
|
unmatchedFiles: [
|
|
125
192
|
"server/helpers/DataUtils.java",
|
|
@@ -128,18 +195,32 @@ describe("buildAnalysisOutputText — unmatchedFiles / Step 2.3 caller-tracing",
|
|
|
128
195
|
],
|
|
129
196
|
});
|
|
130
197
|
const output = buildAnalysisOutputText(params);
|
|
131
|
-
|
|
198
|
+
const label = getStepTraceCallers(params);
|
|
199
|
+
expect(label).not.toBeNull();
|
|
200
|
+
expect(output).toContain(`Step ${label}`);
|
|
132
201
|
expect(output).toContain("DataUtils.java");
|
|
133
202
|
expect(output).not.toContain("ActionButton.tsx");
|
|
134
203
|
expect(output).not.toContain("package.json");
|
|
135
204
|
});
|
|
136
|
-
it("omits
|
|
137
|
-
//
|
|
138
|
-
//
|
|
139
|
-
|
|
140
|
-
|
|
205
|
+
it("omits trace-callers when unmatchedFiles contains frontend .ts/.js files and isUIOnly is true", () => {
|
|
206
|
+
// Files in recognized frontend directories (components/, pages/) are classified
|
|
207
|
+
// as frontend by isFrontendFile() — making this a UI-only PR.
|
|
208
|
+
const params = baseParams({
|
|
209
|
+
parsedDiff: {
|
|
210
|
+
changedFiles: ["src/components/AuthForm.ts", "src/pages/LoginPage.ts"],
|
|
211
|
+
newEndpoints: [],
|
|
212
|
+
modifiedEndpoints: [],
|
|
213
|
+
},
|
|
214
|
+
unmatchedFiles: ["src/components/AuthForm.ts", "src/pages/LoginPage.ts"],
|
|
215
|
+
});
|
|
216
|
+
const output = buildAnalysisOutputText(params);
|
|
217
|
+
expect(getStepTraceCallers(params)).toBeNull();
|
|
218
|
+
expect(output).not.toContain("Trace callers of changed non-route files");
|
|
219
|
+
});
|
|
220
|
+
it("does NOT treat backend .ts/.js files as UI-only (directory-aware heuristic)", () => {
|
|
221
|
+
// Files in src/services/ or src/hooks/ are NOT in frontend directories —
|
|
222
|
+
// they should NOT trigger isUIOnly, so trace-callers should fire.
|
|
141
223
|
const params = baseParams({
|
|
142
|
-
// parsedDiff.changedFiles drives isUIOnly detection; all frontend-ext → isUIOnly=true
|
|
143
224
|
parsedDiff: {
|
|
144
225
|
changedFiles: ["src/services/auth.service.ts", "src/hooks/useAuth.ts"],
|
|
145
226
|
newEndpoints: [],
|
|
@@ -148,7 +229,35 @@ describe("buildAnalysisOutputText — unmatchedFiles / Step 2.3 caller-tracing",
|
|
|
148
229
|
unmatchedFiles: ["src/services/auth.service.ts", "src/hooks/useAuth.ts"],
|
|
149
230
|
});
|
|
150
231
|
const output = buildAnalysisOutputText(params);
|
|
151
|
-
expect(
|
|
152
|
-
expect(output).
|
|
232
|
+
expect(getStepTraceCallers(params)).not.toBeNull();
|
|
233
|
+
expect(output).toContain("Trace callers of changed non-route files");
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
describe("buildAnalysisOutputText — scanner fallback", () => {
|
|
237
|
+
it("includes manual endpoint discovery in diff scope when candidate route files are present despite scanned endpoints", () => {
|
|
238
|
+
const params = baseParams({
|
|
239
|
+
analysisScope: AnalysisScope.CurrentBranchDiff,
|
|
240
|
+
scannedEndpoints: [{ path: "/openapi-only", methods: ["GET"], sourceFile: "" }],
|
|
241
|
+
candidateRouteFiles: ["src/routes/items.ts"],
|
|
242
|
+
});
|
|
243
|
+
const output = buildAnalysisOutputText(params);
|
|
244
|
+
expect(output).toContain("Scanner Fallback — Manual Endpoint Discovery Required");
|
|
245
|
+
expect(output).toContain("may have missed route/controller files");
|
|
246
|
+
expect(output).toContain("src/routes/items.ts");
|
|
247
|
+
expect(output).toContain("supplemental gap check");
|
|
248
|
+
expect(output).toContain("keep the existing catalog as the primary endpoint source");
|
|
249
|
+
expect(output).not.toContain("use it as the authoritative endpoint list");
|
|
250
|
+
});
|
|
251
|
+
it("tells fallback discovery not to turn GraphQL artifacts into REST endpoints", () => {
|
|
252
|
+
const params = baseParams({
|
|
253
|
+
analysisScope: AnalysisScope.CurrentBranchDiff,
|
|
254
|
+
scannedEndpoints: [],
|
|
255
|
+
candidateRouteFiles: ["src/graphql/users.resolver.ts"],
|
|
256
|
+
});
|
|
257
|
+
const output = buildAnalysisOutputText(params);
|
|
258
|
+
expect(output).toContain("GraphQL: schema/resolver artifacts are unsupported for REST test generation");
|
|
259
|
+
expect(output).toContain("do not invent REST endpoints from them");
|
|
260
|
+
expect(output).toContain("use it as the authoritative endpoint list");
|
|
261
|
+
expect(output).not.toContain("Query/Mutation resolvers mapping to endpoints");
|
|
153
262
|
});
|
|
154
263
|
});
|