@skyramp/mcp 0.3.2-rc.pom-3 → 0.3.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/commands/commandLibrary.d.ts +1 -0
- package/build/commands/commandLibrary.js +19 -13
- package/build/commands/localDevTestChangesCommand.d.ts +15 -0
- package/build/commands/localDevTestChangesCommand.js +201 -0
- package/build/index.js +80 -6
- package/build/prompts/code-reuse.js +3 -0
- package/build/prompts/enhance-assertions/sharedAssertionRules.d.ts +1 -0
- package/build/prompts/enhance-assertions/sharedAssertionRules.js +17 -0
- package/build/prompts/initialize-workspace/initializeWorkspacePrompt.js +11 -9
- package/build/prompts/local-dev/local-dev-plan.d.ts +35 -0
- package/build/prompts/local-dev/local-dev-plan.js +429 -0
- package/build/prompts/local-dev/local-dev-prompts.d.ts +4 -0
- package/build/prompts/local-dev/local-dev-prompts.js +190 -0
- package/build/prompts/pom-aware-code-reuse.js +12 -0
- package/build/prompts/prompt-utils.d.ts +8 -0
- package/build/prompts/prompt-utils.js +33 -0
- package/build/prompts/sut-setup/modes/adaptWorkflowPrompt.js +37 -14
- package/build/prompts/sut-setup/shared.js +16 -12
- package/build/prompts/test-recommendation/analysisOutputPrompt.js +21 -29
- package/build/prompts/test-recommendation/scopeAssessment.d.ts +24 -7
- package/build/prompts/test-recommendation/scopeAssessment.js +111 -12
- package/build/prompts/test-recommendation/test-recommendation-prompt.js +41 -4
- package/build/prompts/testbot/testbot-prompts.d.ts +0 -5
- package/build/prompts/testbot/testbot-prompts.js +32 -52
- package/build/recommendation/planRanker.d.ts +15 -2
- package/build/recommendation/planRanker.js +76 -5
- package/build/resources/testbotResource.js +2 -1
- package/build/services/AnalyticsService.d.ts +1 -1
- package/build/services/TestExecutionService.d.ts +2 -1
- package/build/services/TestExecutionService.js +8 -3
- package/build/services/TestGenerationService.d.ts +2 -2
- package/build/services/TestGenerationService.js +39 -21
- package/build/services/containerEnv.js +3 -1
- package/build/tool-phases.js +6 -0
- package/build/tools/code-refactor/codeReuseTool.js +43 -4
- package/build/tools/code-refactor/enhanceAssertionsTool.js +68 -18
- package/build/tools/code-refactor/reuse-outcome.d.ts +109 -0
- package/build/tools/code-refactor/reuse-outcome.js +158 -0
- package/build/tools/code-refactor/reuse-state.d.ts +45 -0
- package/build/tools/code-refactor/reuse-state.js +140 -0
- package/build/tools/enrichTestWithMocksTool.d.ts +28 -0
- package/build/tools/enrichTestWithMocksTool.js +726 -0
- package/build/tools/executeSkyrampTestTool.d.ts +11 -0
- package/build/tools/executeSkyrampTestTool.js +62 -21
- package/build/tools/generate-tests/batchMockGenerationTool.d.ts +106 -0
- package/build/tools/generate-tests/batchMockGenerationTool.js +545 -0
- package/build/tools/generate-tests/generateBatchScenarioRestTool.js +25 -23
- package/build/tools/generate-tests/generateContractRestTool.js +2 -2
- package/build/tools/generate-tests/generateE2ERestTool.d.ts +1 -1
- package/build/tools/generate-tests/generateE2ERestTool.js +1 -1
- package/build/tools/generate-tests/generateLoadRestTool.d.ts +1 -1
- package/build/tools/generate-tests/generateLoadRestTool.js +1 -1
- package/build/tools/generate-tests/generateMockRestTool.d.ts +179 -6
- package/build/tools/generate-tests/generateMockRestTool.js +391 -22
- package/build/tools/generate-tests/loadTestSchema.d.ts +1 -1
- package/build/tools/generate-tests/planGuard.js +2 -22
- package/build/tools/generateEnrichedIntegrationTestTool.d.ts +25 -0
- package/build/tools/generateEnrichedIntegrationTestTool.js +235 -0
- package/build/tools/localDevWorkerComposeTool.d.ts +24 -0
- package/build/tools/localDevWorkerComposeTool.js +264 -0
- package/build/tools/one-click/oneClickTool.d.ts +13 -0
- package/build/tools/one-click/oneClickTool.js +195 -24
- package/build/tools/preflightMockCheckTool.d.ts +2 -0
- package/build/tools/preflightMockCheckTool.js +96 -0
- package/build/tools/queryProxyMocksTool.d.ts +70 -0
- package/build/tools/queryProxyMocksTool.js +522 -0
- package/build/tools/runExistingTestsTool.d.ts +31 -0
- package/build/tools/runExistingTestsTool.js +214 -13
- package/build/tools/submitReportTool.js +38 -3
- package/build/tools/test-management/analyzeChangesTool.d.ts +2 -1
- package/build/tools/test-management/analyzeChangesTool.js +63 -40
- package/build/tools/test-management/registerTestPlanTool.js +55 -7
- package/build/tools/trace/startTraceCollectionTool.js +3 -3
- package/build/types/FrontendIntegration.d.ts +3 -0
- package/build/types/FrontendIntegration.js +3 -0
- package/build/types/OneClickCommands.d.ts +1 -1
- package/build/types/Recommendation.d.ts +20 -0
- package/build/types/Recommendation.js +32 -6
- package/build/types/RepositoryAnalysis.d.ts +131 -14
- package/build/types/RepositoryAnalysis.js +16 -2
- package/build/types/ReuseOutcome.d.ts +63 -0
- package/build/types/ReuseOutcome.js +33 -0
- package/build/types/TestExecution.d.ts +1 -0
- package/build/types/TestTypes.d.ts +25 -7
- package/build/types/TestTypes.js +22 -6
- package/build/types/TestbotReport.d.ts +7 -0
- package/build/types/index.d.ts +2 -0
- package/build/types/index.js +1 -0
- package/build/utils/AnalysisStateManager.d.ts +26 -0
- package/build/utils/AnalysisStateManager.js +31 -1
- package/build/utils/analyze-openapi.js +18 -1
- package/build/utils/branchDiff.d.ts +17 -1
- package/build/utils/branchDiff.js +99 -14
- package/build/utils/featureFlags.d.ts +31 -0
- package/build/utils/featureFlags.js +37 -0
- package/build/utils/frontendIntegration.js +8 -1
- package/build/utils/grpcMockValidation.d.ts +1 -0
- package/build/utils/grpcMockValidation.js +49 -0
- package/build/utils/httpMethodValidation.d.ts +4 -0
- package/build/utils/httpMethodValidation.js +15 -0
- package/build/utils/logger.js +1 -1
- package/build/utils/mockCompatibility.d.ts +49 -0
- package/build/utils/mockCompatibility.js +82 -0
- package/build/utils/pom-scope/pom-files.js +7 -0
- package/build/utils/pom-verify/bindings.js +11 -1
- package/build/utils/pom-verify/re-exports.d.ts +10 -0
- package/build/utils/pom-verify/re-exports.js +61 -0
- package/build/utils/pom-verify/resolve.d.ts +4 -1
- package/build/utils/pom-verify/resolve.js +7 -4
- package/build/utils/pom-verify/verify.d.ts +5 -0
- package/build/utils/pom-verify/verify.js +25 -3
- package/build/utils/progress.js +10 -5
- package/build/utils/proxy-terminal.js +3 -3
- package/build/utils/routeParsers.d.ts +3 -9
- package/build/utils/routeParsers.js +79 -4
- package/build/utils/utils.js +2 -2
- package/build/utils/versions.d.ts +4 -3
- package/build/utils/versions.js +3 -1
- package/build/utils/workspaceAuth.d.ts +46 -0
- package/build/utils/workspaceAuth.js +156 -1
- package/build/workspace/testSuites.d.ts +2 -1
- package/build/workspace/testSuites.js +1 -1
- package/build/workspace/workspace.d.ts +108 -32
- package/build/workspace/workspace.js +32 -4
- package/package.json +5 -2
- package/build/adapters/jestAdapter.test.d.ts +0 -1
- package/build/adapters/jestAdapter.test.js +0 -93
- package/build/adapters/mochaAdapter.test.d.ts +0 -1
- package/build/adapters/mochaAdapter.test.js +0 -63
- package/build/adapters/playwrightAdapter.test.d.ts +0 -1
- package/build/adapters/playwrightAdapter.test.js +0 -169
- package/build/adapters/pytestAdapter.test.d.ts +0 -1
- package/build/adapters/pytestAdapter.test.js +0 -90
- package/build/prompts/code-reuse.test.d.ts +0 -1
- package/build/prompts/code-reuse.test.js +0 -62
- package/build/prompts/pom-aware-code-reuse.test.d.ts +0 -1
- package/build/prompts/pom-aware-code-reuse.test.js +0 -11
- package/build/prompts/test-maintenance/drift-analysis-prompt.test.d.ts +0 -1
- package/build/prompts/test-maintenance/drift-analysis-prompt.test.js +0 -51
- package/build/prompts/test-recommendation/analysisOutputPrompt.test.d.ts +0 -1
- package/build/prompts/test-recommendation/analysisOutputPrompt.test.js +0 -264
- package/build/prompts/test-recommendation/mergeEnrichedScenarios.test.d.ts +0 -1
- package/build/prompts/test-recommendation/mergeEnrichedScenarios.test.js +0 -126
- package/build/prompts/test-recommendation/promptPlan.test.d.ts +0 -1
- package/build/prompts/test-recommendation/promptPlan.test.js +0 -336
- package/build/prompts/test-recommendation/scopeAssessment.test.d.ts +0 -1
- package/build/prompts/test-recommendation/scopeAssessment.test.js +0 -371
- package/build/prompts/test-recommendation/test-recommendation-prompt.test.d.ts +0 -1
- package/build/prompts/test-recommendation/test-recommendation-prompt.test.js +0 -1925
- package/build/prompts/testbot/testbot-prompts.test.d.ts +0 -1
- package/build/prompts/testbot/testbot-prompts.test.js +0 -451
- package/build/recommendation/budgeters/diversityBalancedBudgeter.test.d.ts +0 -1
- package/build/recommendation/budgeters/diversityBalancedBudgeter.test.js +0 -138
- package/build/recommendation/budgeters/fixedNBudgeter.test.d.ts +0 -1
- package/build/recommendation/budgeters/fixedNBudgeter.test.js +0 -66
- package/build/recommendation/discriminators.test.d.ts +0 -1
- package/build/recommendation/discriminators.test.js +0 -324
- package/build/recommendation/diversity.test.d.ts +0 -1
- package/build/recommendation/diversity.test.js +0 -77
- package/build/recommendation/planRanker.test.d.ts +0 -1
- package/build/recommendation/planRanker.test.js +0 -110
- package/build/resources/testbotResource.test.d.ts +0 -1
- package/build/resources/testbotResource.test.js +0 -44
- package/build/services/AnalyticsService.test.d.ts +0 -1
- package/build/services/AnalyticsService.test.js +0 -86
- package/build/services/ScenarioGenerationService.integration.test.d.ts +0 -1
- package/build/services/ScenarioGenerationService.integration.test.js +0 -162
- package/build/services/ScenarioGenerationService.test.d.ts +0 -1
- package/build/services/ScenarioGenerationService.test.js +0 -414
- package/build/services/TestDiscoveryService.test.d.ts +0 -1
- package/build/services/TestDiscoveryService.test.js +0 -983
- package/build/services/TestExecutionService.test.d.ts +0 -1
- package/build/services/TestExecutionService.test.js +0 -1032
- package/build/services/TestGenerationService.test.d.ts +0 -1
- package/build/services/TestGenerationService.test.js +0 -578
- package/build/tool-phase-coverage.test.d.ts +0 -1
- package/build/tool-phase-coverage.test.js +0 -49
- package/build/tools/code-refactor/codeReuseTool.test.d.ts +0 -1
- package/build/tools/code-refactor/codeReuseTool.test.js +0 -572
- package/build/tools/generate-tests/generateBatchScenarioRestTool.test.d.ts +0 -1
- package/build/tools/generate-tests/generateBatchScenarioRestTool.test.js +0 -433
- package/build/tools/generate-tests/generateContractRestTool.test.d.ts +0 -1
- package/build/tools/generate-tests/generateContractRestTool.test.js +0 -142
- package/build/tools/generate-tests/generateIntegrationRestTool.test.d.ts +0 -1
- package/build/tools/generate-tests/generateIntegrationRestTool.test.js +0 -159
- package/build/tools/generate-tests/generateLoadRestTool.test.d.ts +0 -1
- package/build/tools/generate-tests/generateLoadRestTool.test.js +0 -169
- package/build/tools/generate-tests/generateUIRestTool.test.d.ts +0 -1
- package/build/tools/generate-tests/generateUIRestTool.test.js +0 -32
- package/build/tools/generate-tests/planGuard.test.d.ts +0 -1
- package/build/tools/generate-tests/planGuard.test.js +0 -185
- package/build/tools/generate-tests/scenarioLint.test.d.ts +0 -1
- package/build/tools/generate-tests/scenarioLint.test.js +0 -100
- package/build/tools/runExistingTestsTool.test.d.ts +0 -1
- package/build/tools/runExistingTestsTool.test.js +0 -379
- package/build/tools/submitReportTool.test.d.ts +0 -1
- package/build/tools/submitReportTool.test.js +0 -1428
- package/build/tools/test-management/actionsTool.test.d.ts +0 -1
- package/build/tools/test-management/actionsTool.test.js +0 -436
- package/build/tools/test-management/analyzeChangesTool.test.d.ts +0 -1
- package/build/tools/test-management/analyzeChangesTool.test.js +0 -522
- package/build/tools/test-management/analyzeTestHealthTool.test.d.ts +0 -1
- package/build/tools/test-management/analyzeTestHealthTool.test.js +0 -385
- package/build/tools/test-management/registerTestPlanTool.test.d.ts +0 -1
- package/build/tools/test-management/registerTestPlanTool.test.js +0 -296
- package/build/tools/trace/resolveSaveStoragePath.test.d.ts +0 -1
- package/build/tools/trace/resolveSaveStoragePath.test.js +0 -17
- package/build/tools/trace/resolveSessionPaths.test.d.ts +0 -1
- package/build/tools/trace/resolveSessionPaths.test.js +0 -104
- package/build/tools/trace/sessionState.test.d.ts +0 -1
- package/build/tools/trace/sessionState.test.js +0 -17
- package/build/tools/workspace/initializeWorkspaceTool.test.d.ts +0 -1
- package/build/tools/workspace/initializeWorkspaceTool.test.js +0 -139
- package/build/tools/workspace/serviceUpsert.test.d.ts +0 -1
- package/build/tools/workspace/serviceUpsert.test.js +0 -50
- package/build/utils/AnalysisStateManager.test.d.ts +0 -1
- package/build/utils/AnalysisStateManager.test.js +0 -134
- package/build/utils/dartRouteExtractor.test.d.ts +0 -1
- package/build/utils/dartRouteExtractor.test.js +0 -307
- package/build/utils/docker.test.d.ts +0 -1
- package/build/utils/docker.test.js +0 -114
- package/build/utils/featureFlags.test.d.ts +0 -1
- package/build/utils/featureFlags.test.js +0 -81
- package/build/utils/fileWalk.test.d.ts +0 -1
- package/build/utils/fileWalk.test.js +0 -252
- package/build/utils/frontendIntegration.test.d.ts +0 -1
- package/build/utils/frontendIntegration.test.js +0 -229
- package/build/utils/frontendSelectors.test.d.ts +0 -1
- package/build/utils/frontendSelectors.test.js +0 -118
- package/build/utils/gitStaging.test.d.ts +0 -1
- package/build/utils/gitStaging.test.js +0 -111
- package/build/utils/httpDefaults.test.d.ts +0 -1
- package/build/utils/httpDefaults.test.js +0 -21
- package/build/utils/importerHop.test.d.ts +0 -1
- package/build/utils/importerHop.test.js +0 -469
- package/build/utils/pathAffinityClassification.test.d.ts +0 -1
- package/build/utils/pathAffinityClassification.test.js +0 -208
- package/build/utils/planMatchKeys.test.d.ts +0 -1
- package/build/utils/planMatchKeys.test.js +0 -123
- package/build/utils/pom-scope/index.test.d.ts +0 -1
- package/build/utils/pom-scope/index.test.js +0 -278
- package/build/utils/pom-scope/pom-files.test.d.ts +0 -1
- package/build/utils/pom-scope/pom-files.test.js +0 -29
- package/build/utils/pom-scope/scoring.test.d.ts +0 -1
- package/build/utils/pom-scope/scoring.test.js +0 -39
- package/build/utils/pom-scope/selector-extractor.test.d.ts +0 -1
- package/build/utils/pom-scope/selector-extractor.test.js +0 -67
- package/build/utils/pom-verify/bindings.test.d.ts +0 -1
- package/build/utils/pom-verify/bindings.test.js +0 -164
- package/build/utils/pom-verify/calls.test.d.ts +0 -1
- package/build/utils/pom-verify/calls.test.js +0 -61
- package/build/utils/pom-verify/resolve.test.d.ts +0 -1
- package/build/utils/pom-verify/resolve.test.js +0 -114
- package/build/utils/pom-verify/verify.test.d.ts +0 -1
- package/build/utils/pom-verify/verify.test.js +0 -374
- package/build/utils/pr-comment-parser.test.d.ts +0 -1
- package/build/utils/pr-comment-parser.test.js +0 -428
- package/build/utils/progress.test.d.ts +0 -1
- package/build/utils/progress.test.js +0 -37
- package/build/utils/projectMetadata.test.d.ts +0 -1
- package/build/utils/projectMetadata.test.js +0 -172
- package/build/utils/pythonMountPrefixes.test.d.ts +0 -1
- package/build/utils/pythonMountPrefixes.test.js +0 -113
- package/build/utils/repoScanner.test.d.ts +0 -1
- package/build/utils/repoScanner.test.js +0 -190
- package/build/utils/reportVerification.test.d.ts +0 -1
- package/build/utils/reportVerification.test.js +0 -185
- package/build/utils/routeParsers.test.d.ts +0 -1
- package/build/utils/routeParsers.test.js +0 -1011
- package/build/utils/scenarioDrafting.test.d.ts +0 -1
- package/build/utils/scenarioDrafting.test.js +0 -876
- package/build/utils/sourceRouteExtractor.test.d.ts +0 -1
- package/build/utils/sourceRouteExtractor.test.js +0 -738
- package/build/utils/telemetry.test.d.ts +0 -1
- package/build/utils/telemetry.test.js +0 -70
- package/build/utils/trace-parser.test.d.ts +0 -6
- package/build/utils/trace-parser.test.js +0 -140
- package/build/utils/uiPageEnumerator.test.d.ts +0 -1
- package/build/utils/uiPageEnumerator.test.js +0 -824
- package/build/utils/utils.test.d.ts +0 -1
- package/build/utils/utils.test.js +0 -103
- package/build/utils/walkerCharacterization.test.d.ts +0 -1
- package/build/utils/walkerCharacterization.test.js +0 -233
- package/build/utils/workspaceAuth.test.d.ts +0 -1
- package/build/utils/workspaceAuth.test.js +0 -260
- package/build/workspace/testSuites.test.d.ts +0 -1
- package/build/workspace/testSuites.test.js +0 -23
- package/build/workspace/workspace.test.d.ts +0 -1
- package/build/workspace/workspace.test.js +0 -264
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,578 +0,0 @@
|
|
|
1
|
-
// @ts-nocheck - Jest ESM type inference issues
|
|
2
|
-
import { jest } from "@jest/globals";
|
|
3
|
-
import { TestType } from "../types/TestTypes.js";
|
|
4
|
-
import { AUTH_PLACEHOLDER_TOKEN } from "../types/TestTypes.js";
|
|
5
|
-
import fs from "fs";
|
|
6
|
-
import os from "os";
|
|
7
|
-
import path from "path";
|
|
8
|
-
// Mock @skyramp/skyramp before importing TestGenerationService to avoid
|
|
9
|
-
// pulling in playwright (dynamic imports fail on Node 18 in CI). Under native
|
|
10
|
-
// ESM, jest.mock is not hoisted — use unstable_mockModule + dynamic import.
|
|
11
|
-
jest.unstable_mockModule("@skyramp/skyramp", () => ({
|
|
12
|
-
SkyrampClient: jest.fn().mockImplementation(() => ({})),
|
|
13
|
-
}));
|
|
14
|
-
const { TestGenerationService, deriveEffectiveFramework } = await import("./TestGenerationService.js");
|
|
15
|
-
const { SkyrampClient } = await import("@skyramp/skyramp");
|
|
16
|
-
class StubService extends TestGenerationService {
|
|
17
|
-
buildGenerationOptions() {
|
|
18
|
-
return {};
|
|
19
|
-
}
|
|
20
|
-
getTestType() {
|
|
21
|
-
return TestType.SMOKE;
|
|
22
|
-
}
|
|
23
|
-
validate(params) {
|
|
24
|
-
return this.validateInputs(params);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
const BASE = {
|
|
28
|
-
outputDir: "/tmp/tests",
|
|
29
|
-
force: true,
|
|
30
|
-
};
|
|
31
|
-
function validateOutput(framework, output) {
|
|
32
|
-
const svc = new StubService();
|
|
33
|
-
return svc.validate({ ...BASE, framework, output });
|
|
34
|
-
}
|
|
35
|
-
function playwrightError(result) {
|
|
36
|
-
for (const c of result.content) {
|
|
37
|
-
if (c.type === "text" && c.text.includes("Playwright")) {
|
|
38
|
-
return c.text;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return undefined;
|
|
42
|
-
}
|
|
43
|
-
describe("TestGenerationService — Playwright filename validation", () => {
|
|
44
|
-
it.each([
|
|
45
|
-
"my_test.spec.ts",
|
|
46
|
-
"my_test.test.ts",
|
|
47
|
-
"my_test.spec.js",
|
|
48
|
-
"my_test.test.js",
|
|
49
|
-
])("accepts valid Playwright filename: %s", (filename) => {
|
|
50
|
-
const result = validateOutput("playwright", filename);
|
|
51
|
-
expect(playwrightError(result)).toBeUndefined();
|
|
52
|
-
});
|
|
53
|
-
it.each([
|
|
54
|
-
"my_test.ts",
|
|
55
|
-
"my_test.py",
|
|
56
|
-
"my_test.java",
|
|
57
|
-
"tests",
|
|
58
|
-
"my_test.js",
|
|
59
|
-
])("rejects invalid Playwright filename: %s", (filename) => {
|
|
60
|
-
const result = validateOutput("playwright", filename);
|
|
61
|
-
expect(playwrightError(result)).toBeDefined();
|
|
62
|
-
expect(playwrightError(result)).toContain("Playwright requires");
|
|
63
|
-
});
|
|
64
|
-
it("suggests .spec.ts replacement for .ts file", () => {
|
|
65
|
-
const err = playwrightError(validateOutput("playwright", "crud_items.ts"));
|
|
66
|
-
expect(err).toContain("crud_items.spec.ts");
|
|
67
|
-
});
|
|
68
|
-
it("suggests .spec.ts replacement for .js file", () => {
|
|
69
|
-
const err = playwrightError(validateOutput("playwright", "crud_items.js"));
|
|
70
|
-
expect(err).toContain("crud_items.spec.ts");
|
|
71
|
-
});
|
|
72
|
-
it("appends .spec.ts for non-JS extension (e.g. .java)", () => {
|
|
73
|
-
const err = playwrightError(validateOutput("playwright", "my_test.java"));
|
|
74
|
-
expect(err).toContain("my_test.java.spec.ts");
|
|
75
|
-
});
|
|
76
|
-
it("appends .spec.ts for extensionless filename", () => {
|
|
77
|
-
const err = playwrightError(validateOutput("playwright", "tests"));
|
|
78
|
-
expect(err).toContain("tests.spec.ts");
|
|
79
|
-
});
|
|
80
|
-
it("skips validation when output is empty string", () => {
|
|
81
|
-
expect(playwrightError(validateOutput("playwright", ""))).toBeUndefined();
|
|
82
|
-
});
|
|
83
|
-
it("skips validation for non-playwright frameworks", () => {
|
|
84
|
-
expect(playwrightError(validateOutput("pytest", "my_test.py"))).toBeUndefined();
|
|
85
|
-
});
|
|
86
|
-
it("is case-insensitive on framework name", () => {
|
|
87
|
-
expect(playwrightError(validateOutput("Playwright", "bad.ts"))).toBeDefined();
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
describe("TestGenerationService — language/output extension consistency (SKYR-3899)", () => {
|
|
91
|
-
function validateLangOutput(language, framework, output) {
|
|
92
|
-
const svc = new StubService();
|
|
93
|
-
return svc.validate({ ...BASE, language, framework, output });
|
|
94
|
-
}
|
|
95
|
-
function errorText(result) {
|
|
96
|
-
for (const c of result.content) {
|
|
97
|
-
if (c.type === "text")
|
|
98
|
-
return c.text;
|
|
99
|
-
}
|
|
100
|
-
return undefined;
|
|
101
|
-
}
|
|
102
|
-
it("rejects TypeScript output written to a .py file with no explicit framework (the reported bug)", () => {
|
|
103
|
-
// language typescript + no framework derives to playwright, so ui_test.py is
|
|
104
|
-
// rejected instead of emitting TypeScript into a Python file.
|
|
105
|
-
const result = validateLangOutput("typescript", "", "ui_test.py");
|
|
106
|
-
expect(result.isError).toBe(true);
|
|
107
|
-
expect(errorText(result)).toContain("Playwright requires");
|
|
108
|
-
});
|
|
109
|
-
it("accepts a TypeScript UI test named *.spec.ts with no explicit framework", () => {
|
|
110
|
-
const result = validateLangOutput("typescript", "", "ui_test.spec.ts");
|
|
111
|
-
expect(result.isError).toBe(false);
|
|
112
|
-
});
|
|
113
|
-
it("rejects a Python-language test written to a .ts file", () => {
|
|
114
|
-
const result = validateLangOutput("python", "", "my_test.ts");
|
|
115
|
-
expect(result.isError).toBe(true);
|
|
116
|
-
expect(errorText(result)).toContain('language "python" requires a .py');
|
|
117
|
-
expect(errorText(result)).toContain("my_test.py");
|
|
118
|
-
});
|
|
119
|
-
it("accepts a Python-language test written to a .py file", () => {
|
|
120
|
-
const result = validateLangOutput("python", "", "my_test.py");
|
|
121
|
-
expect(result.isError).toBe(false);
|
|
122
|
-
});
|
|
123
|
-
it("rejects a mismatched extension even when a non-playwright framework is explicit", () => {
|
|
124
|
-
const result = validateLangOutput("typescript", "pytest", "foo.py");
|
|
125
|
-
expect(result.isError).toBe(true);
|
|
126
|
-
expect(errorText(result)).toContain('language "typescript" requires a .ts');
|
|
127
|
-
});
|
|
128
|
-
it("accepts a Python Playwright test (pytest-playwright) written to a .py file", () => {
|
|
129
|
-
// Playwright supports Python via pytest-playwright — language: "python" +
|
|
130
|
-
// framework: "playwright" must validate against .py, not the js/ts spec rule.
|
|
131
|
-
const result = validateLangOutput("python", "playwright", "test_login.py");
|
|
132
|
-
expect(result.isError).toBe(false);
|
|
133
|
-
});
|
|
134
|
-
it("rejects a Python Playwright test written to a .spec.ts file", () => {
|
|
135
|
-
const result = validateLangOutput("python", "playwright", "foo.spec.ts");
|
|
136
|
-
expect(result.isError).toBe(true);
|
|
137
|
-
expect(errorText(result)).toContain('language "python" requires a .py');
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
describe("deriveEffectiveFramework — validation/generation share one derivation (SKYR-3899)", () => {
|
|
141
|
-
it("derives playwright for ts/js when framework is undefined", () => {
|
|
142
|
-
expect(deriveEffectiveFramework("typescript", undefined)).toBe("playwright");
|
|
143
|
-
expect(deriveEffectiveFramework("javascript", undefined)).toBe("playwright");
|
|
144
|
-
});
|
|
145
|
-
it("treats a blank/whitespace framework as unset (no drift vs undefined)", () => {
|
|
146
|
-
// The empty-string edge the two call sites used to disagree on: validation
|
|
147
|
-
// derived playwright while generation kept "". Both now agree.
|
|
148
|
-
expect(deriveEffectiveFramework("typescript", "")).toBe("playwright");
|
|
149
|
-
expect(deriveEffectiveFramework("typescript", " ")).toBe("playwright");
|
|
150
|
-
});
|
|
151
|
-
it("keeps an explicit framework and defaults non-js/ts to empty", () => {
|
|
152
|
-
expect(deriveEffectiveFramework("typescript", "pytest")).toBe("pytest");
|
|
153
|
-
expect(deriveEffectiveFramework("python", undefined)).toBe("");
|
|
154
|
-
});
|
|
155
|
-
});
|
|
156
|
-
describe("TestGenerationService — authType/authScheme not passed to library", () => {
|
|
157
|
-
let mockGenerateRestTest;
|
|
158
|
-
beforeEach(() => {
|
|
159
|
-
mockGenerateRestTest = jest.fn().mockResolvedValue("Test generation success");
|
|
160
|
-
SkyrampClient.mockImplementation(() => ({
|
|
161
|
-
generateRestTest: mockGenerateRestTest,
|
|
162
|
-
}));
|
|
163
|
-
});
|
|
164
|
-
it("maps authScheme to authType for the npm client", async () => {
|
|
165
|
-
const svc = new StubService();
|
|
166
|
-
svc.buildGenerationOptions = () => ({
|
|
167
|
-
authHeader: "Authorization",
|
|
168
|
-
authScheme: "Token",
|
|
169
|
-
authType: "Token",
|
|
170
|
-
outputDir: "/tmp/tests",
|
|
171
|
-
language: "python",
|
|
172
|
-
framework: "pytest",
|
|
173
|
-
});
|
|
174
|
-
svc.handleApiAnalysis = async () => null;
|
|
175
|
-
await svc.generateTest({ ...BASE });
|
|
176
|
-
const callArgs = mockGenerateRestTest.mock.calls[0][0];
|
|
177
|
-
expect(callArgs.authType).toBe("Token");
|
|
178
|
-
expect(callArgs.authScheme).toBeUndefined();
|
|
179
|
-
// authHeader is cleared for Authorization when authType is set (CLI conflict fix)
|
|
180
|
-
expect(callArgs.authHeader).toBeUndefined();
|
|
181
|
-
});
|
|
182
|
-
it("passes authHeader through to library without modification", async () => {
|
|
183
|
-
const svc = new StubService();
|
|
184
|
-
svc.buildGenerationOptions = () => ({
|
|
185
|
-
authHeader: "X-Api-Key",
|
|
186
|
-
outputDir: "/tmp/tests",
|
|
187
|
-
language: "python",
|
|
188
|
-
framework: "pytest",
|
|
189
|
-
});
|
|
190
|
-
svc.handleApiAnalysis = async () => null;
|
|
191
|
-
await svc.generateTest({ ...BASE });
|
|
192
|
-
const callArgs = mockGenerateRestTest.mock.calls[0][0];
|
|
193
|
-
expect(callArgs.authHeader).toBe("X-Api-Key");
|
|
194
|
-
expect(callArgs.authType).toBeUndefined();
|
|
195
|
-
expect(callArgs.authScheme).toBeUndefined();
|
|
196
|
-
});
|
|
197
|
-
});
|
|
198
|
-
describe("TestGenerationService — extractAuthFromTrace", () => {
|
|
199
|
-
let tmpDir;
|
|
200
|
-
beforeEach(() => {
|
|
201
|
-
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "skyramp-test-"));
|
|
202
|
-
});
|
|
203
|
-
afterEach(() => {
|
|
204
|
-
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
205
|
-
});
|
|
206
|
-
function writeTrace(requests) {
|
|
207
|
-
const filePath = path.join(tmpDir, "trace.json");
|
|
208
|
-
fs.writeFileSync(filePath, JSON.stringify(requests), "utf8");
|
|
209
|
-
return filePath;
|
|
210
|
-
}
|
|
211
|
-
function extract(filePath, include, exclude) {
|
|
212
|
-
const svc = new StubService();
|
|
213
|
-
return svc.extractAuthFromTrace(filePath, include, exclude);
|
|
214
|
-
}
|
|
215
|
-
it("extracts Authorization + Bearer scheme from trace", () => {
|
|
216
|
-
const fp = writeTrace([
|
|
217
|
-
{
|
|
218
|
-
RequestHeaders: {
|
|
219
|
-
"Content-Type": ["application/json"],
|
|
220
|
-
Authorization: [`Bearer ${AUTH_PLACEHOLDER_TOKEN}`],
|
|
221
|
-
},
|
|
222
|
-
},
|
|
223
|
-
]);
|
|
224
|
-
expect(extract(fp)).toEqual({
|
|
225
|
-
authHeader: "Authorization",
|
|
226
|
-
authScheme: "Bearer",
|
|
227
|
-
});
|
|
228
|
-
});
|
|
229
|
-
it("extracts Authorization + Token scheme from trace", () => {
|
|
230
|
-
const fp = writeTrace([
|
|
231
|
-
{
|
|
232
|
-
RequestHeaders: {
|
|
233
|
-
"Content-Type": ["application/json"],
|
|
234
|
-
Authorization: [`Token ${AUTH_PLACEHOLDER_TOKEN}`],
|
|
235
|
-
},
|
|
236
|
-
},
|
|
237
|
-
]);
|
|
238
|
-
expect(extract(fp)).toEqual({
|
|
239
|
-
authHeader: "Authorization",
|
|
240
|
-
authScheme: "Token",
|
|
241
|
-
});
|
|
242
|
-
});
|
|
243
|
-
it("extracts X-Api-Key with empty scheme from trace", () => {
|
|
244
|
-
const fp = writeTrace([
|
|
245
|
-
{
|
|
246
|
-
RequestHeaders: {
|
|
247
|
-
"Content-Type": ["application/json"],
|
|
248
|
-
"X-Api-Key": [AUTH_PLACEHOLDER_TOKEN],
|
|
249
|
-
},
|
|
250
|
-
},
|
|
251
|
-
]);
|
|
252
|
-
expect(extract(fp)).toEqual({
|
|
253
|
-
authHeader: "X-Api-Key",
|
|
254
|
-
authScheme: "",
|
|
255
|
-
});
|
|
256
|
-
});
|
|
257
|
-
it("returns null when no auth header in trace", () => {
|
|
258
|
-
const fp = writeTrace([
|
|
259
|
-
{
|
|
260
|
-
RequestHeaders: {
|
|
261
|
-
"Content-Type": ["application/json"],
|
|
262
|
-
},
|
|
263
|
-
},
|
|
264
|
-
]);
|
|
265
|
-
expect(extract(fp)).toBeNull();
|
|
266
|
-
});
|
|
267
|
-
it("returns null for invalid JSON", () => {
|
|
268
|
-
const fp = path.join(tmpDir, "bad.json");
|
|
269
|
-
fs.writeFileSync(fp, "not json", "utf8");
|
|
270
|
-
expect(extract(fp)).toBeNull();
|
|
271
|
-
});
|
|
272
|
-
it("returns null for non-existent file", () => {
|
|
273
|
-
expect(extract("/tmp/does-not-exist-xyz.json")).toBeNull();
|
|
274
|
-
});
|
|
275
|
-
it("skips Pragma header (standard HTTP/1.0 caching header, not auth)", () => {
|
|
276
|
-
const fp = writeTrace([
|
|
277
|
-
{
|
|
278
|
-
RequestHeaders: {
|
|
279
|
-
"Cache-Control": ["no-cache"],
|
|
280
|
-
Pragma: ["no-cache"],
|
|
281
|
-
"User-Agent": ["Mozilla/5.0"],
|
|
282
|
-
},
|
|
283
|
-
},
|
|
284
|
-
]);
|
|
285
|
-
expect(extract(fp)).toBeNull();
|
|
286
|
-
});
|
|
287
|
-
it("skips Pragma and finds real auth header behind it", () => {
|
|
288
|
-
const fp = writeTrace([
|
|
289
|
-
{
|
|
290
|
-
RequestHeaders: {
|
|
291
|
-
"Cache-Control": ["no-cache"],
|
|
292
|
-
Pragma: ["no-cache"],
|
|
293
|
-
"User-Agent": ["Mozilla/5.0"],
|
|
294
|
-
Authorization: [`Bearer ${AUTH_PLACEHOLDER_TOKEN}`],
|
|
295
|
-
},
|
|
296
|
-
},
|
|
297
|
-
]);
|
|
298
|
-
expect(extract(fp)).toEqual({
|
|
299
|
-
authHeader: "Authorization",
|
|
300
|
-
authScheme: "Bearer",
|
|
301
|
-
});
|
|
302
|
-
});
|
|
303
|
-
it("uses include filter to skip noise and find auth on matching requests", () => {
|
|
304
|
-
const fp = writeTrace([
|
|
305
|
-
{
|
|
306
|
-
// requests[0]: unrelated traffic (e.g. Google time sync) with no auth
|
|
307
|
-
Destination: "clients2.google.com",
|
|
308
|
-
Path: "/time/1/current",
|
|
309
|
-
RequestHeaders: {
|
|
310
|
-
"Cache-Control": ["no-cache"],
|
|
311
|
-
"User-Agent": ["Mozilla/5.0"],
|
|
312
|
-
},
|
|
313
|
-
},
|
|
314
|
-
{
|
|
315
|
-
// requests[1]: actual API request matching include filter
|
|
316
|
-
Destination: "demoshop.skyramp.dev",
|
|
317
|
-
Path: "/api/v1/products",
|
|
318
|
-
RequestHeaders: {
|
|
319
|
-
"Content-Type": ["application/json"],
|
|
320
|
-
Authorization: [`Bearer ${AUTH_PLACEHOLDER_TOKEN}`],
|
|
321
|
-
},
|
|
322
|
-
},
|
|
323
|
-
]);
|
|
324
|
-
expect(extract(fp, ["demoshop.skyramp.dev/api/*"])).toEqual({
|
|
325
|
-
authHeader: "Authorization",
|
|
326
|
-
authScheme: "Bearer",
|
|
327
|
-
});
|
|
328
|
-
});
|
|
329
|
-
it("uses exclude filter to skip noise and find auth on remaining requests", () => {
|
|
330
|
-
const fp = writeTrace([
|
|
331
|
-
{
|
|
332
|
-
Destination: "clients2.google.com",
|
|
333
|
-
Path: "/time/1/current",
|
|
334
|
-
RequestHeaders: {
|
|
335
|
-
"Cache-Control": ["no-cache"],
|
|
336
|
-
"User-Agent": ["Mozilla/5.0"],
|
|
337
|
-
},
|
|
338
|
-
},
|
|
339
|
-
{
|
|
340
|
-
Destination: "demoshop.skyramp.dev",
|
|
341
|
-
Path: "/api/v1/products",
|
|
342
|
-
RequestHeaders: {
|
|
343
|
-
"Content-Type": ["application/json"],
|
|
344
|
-
Authorization: [`Bearer ${AUTH_PLACEHOLDER_TOKEN}`],
|
|
345
|
-
},
|
|
346
|
-
},
|
|
347
|
-
]);
|
|
348
|
-
expect(extract(fp, undefined, ["clients2.google.com/*"])).toEqual({
|
|
349
|
-
authHeader: "Authorization",
|
|
350
|
-
authScheme: "Bearer",
|
|
351
|
-
});
|
|
352
|
-
});
|
|
353
|
-
it("prefers Authorization over Cookie even when Cookie appears first", () => {
|
|
354
|
-
const fp = writeTrace([
|
|
355
|
-
{
|
|
356
|
-
RequestHeaders: {
|
|
357
|
-
"Content-Type": ["application/json"],
|
|
358
|
-
Cookie: ["cf_clearance=abc123; _dd_s=xyz"],
|
|
359
|
-
Authorization: [`Bearer ${AUTH_PLACEHOLDER_TOKEN}`],
|
|
360
|
-
},
|
|
361
|
-
},
|
|
362
|
-
]);
|
|
363
|
-
expect(extract(fp)).toEqual({
|
|
364
|
-
authHeader: "Authorization",
|
|
365
|
-
authScheme: "Bearer",
|
|
366
|
-
});
|
|
367
|
-
});
|
|
368
|
-
it("falls back to known auth header (X-Api-Key) when no Authorization present", () => {
|
|
369
|
-
const fp = writeTrace([
|
|
370
|
-
{
|
|
371
|
-
RequestHeaders: {
|
|
372
|
-
"Content-Type": ["application/json"],
|
|
373
|
-
"Sec-Fetch-Mode": ["cors"],
|
|
374
|
-
"X-Api-Key": ["my-secret-key"],
|
|
375
|
-
Traceparent: ["00-abc-def-01"],
|
|
376
|
-
},
|
|
377
|
-
},
|
|
378
|
-
]);
|
|
379
|
-
expect(extract(fp)).toEqual({
|
|
380
|
-
authHeader: "X-Api-Key",
|
|
381
|
-
authScheme: "",
|
|
382
|
-
});
|
|
383
|
-
});
|
|
384
|
-
it("skips standard headers like Accept", () => {
|
|
385
|
-
const fp = writeTrace([
|
|
386
|
-
{
|
|
387
|
-
RequestHeaders: {
|
|
388
|
-
"Content-Type": ["application/json"],
|
|
389
|
-
Accept: ["application/json"],
|
|
390
|
-
Authorization: [`Token ${AUTH_PLACEHOLDER_TOKEN}`],
|
|
391
|
-
},
|
|
392
|
-
},
|
|
393
|
-
]);
|
|
394
|
-
expect(extract(fp)).toEqual({
|
|
395
|
-
authHeader: "Authorization",
|
|
396
|
-
authScheme: "Token",
|
|
397
|
-
});
|
|
398
|
-
});
|
|
399
|
-
});
|
|
400
|
-
describe("TestGenerationService — trace-based auth in executeGeneration", () => {
|
|
401
|
-
let mockGenerateRestTest;
|
|
402
|
-
let tmpDir;
|
|
403
|
-
beforeEach(() => {
|
|
404
|
-
mockGenerateRestTest = jest.fn().mockResolvedValue("Test generation success");
|
|
405
|
-
SkyrampClient.mockImplementation(() => ({
|
|
406
|
-
generateRestTest: mockGenerateRestTest,
|
|
407
|
-
}));
|
|
408
|
-
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "skyramp-test-"));
|
|
409
|
-
});
|
|
410
|
-
afterEach(() => {
|
|
411
|
-
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
412
|
-
});
|
|
413
|
-
function writeTrace(requests) {
|
|
414
|
-
const filePath = path.join(tmpDir, "trace.json");
|
|
415
|
-
fs.writeFileSync(filePath, JSON.stringify(requests), "utf8");
|
|
416
|
-
return filePath;
|
|
417
|
-
}
|
|
418
|
-
it("populates authScheme from trace when not provided (clears Authorization authHeader)", async () => {
|
|
419
|
-
const traceFile = writeTrace([
|
|
420
|
-
{
|
|
421
|
-
RequestHeaders: {
|
|
422
|
-
"Content-Type": ["application/json"],
|
|
423
|
-
Authorization: [`Token ${AUTH_PLACEHOLDER_TOKEN}`],
|
|
424
|
-
},
|
|
425
|
-
},
|
|
426
|
-
]);
|
|
427
|
-
const svc = new StubService();
|
|
428
|
-
svc.buildGenerationOptions = () => ({
|
|
429
|
-
traceFilePath: traceFile,
|
|
430
|
-
authHeader: "",
|
|
431
|
-
authScheme: "",
|
|
432
|
-
outputDir: "/tmp/tests",
|
|
433
|
-
language: "python",
|
|
434
|
-
framework: "pytest",
|
|
435
|
-
});
|
|
436
|
-
svc.handleApiAnalysis = async () => null;
|
|
437
|
-
await svc.generateTest({ ...BASE });
|
|
438
|
-
const callArgs = mockGenerateRestTest.mock.calls[0][0];
|
|
439
|
-
// authHeader is cleared for Authorization when authType is set (CLI conflict fix)
|
|
440
|
-
expect(callArgs.authHeader).toBeUndefined();
|
|
441
|
-
expect(callArgs.authType).toBe("Token");
|
|
442
|
-
expect(callArgs.authScheme).toBeUndefined();
|
|
443
|
-
});
|
|
444
|
-
it("populates X-Api-Key from trace with empty authScheme", async () => {
|
|
445
|
-
const traceFile = writeTrace([
|
|
446
|
-
{
|
|
447
|
-
RequestHeaders: {
|
|
448
|
-
"Content-Type": ["application/json"],
|
|
449
|
-
"X-Api-Key": [AUTH_PLACEHOLDER_TOKEN],
|
|
450
|
-
},
|
|
451
|
-
},
|
|
452
|
-
]);
|
|
453
|
-
const svc = new StubService();
|
|
454
|
-
svc.buildGenerationOptions = () => ({
|
|
455
|
-
traceFilePath: traceFile,
|
|
456
|
-
authHeader: "",
|
|
457
|
-
authScheme: "",
|
|
458
|
-
outputDir: "/tmp/tests",
|
|
459
|
-
language: "python",
|
|
460
|
-
framework: "pytest",
|
|
461
|
-
});
|
|
462
|
-
svc.handleApiAnalysis = async () => null;
|
|
463
|
-
await svc.generateTest({ ...BASE });
|
|
464
|
-
const callArgs = mockGenerateRestTest.mock.calls[0][0];
|
|
465
|
-
expect(callArgs.authHeader).toBe("X-Api-Key");
|
|
466
|
-
expect(callArgs.authType).toBe("");
|
|
467
|
-
expect(callArgs.authScheme).toBeUndefined();
|
|
468
|
-
});
|
|
469
|
-
it("overrides conflicting authScheme with trace value and clears Authorization authHeader", async () => {
|
|
470
|
-
const traceFile = writeTrace([
|
|
471
|
-
{
|
|
472
|
-
RequestHeaders: {
|
|
473
|
-
"Content-Type": ["application/json"],
|
|
474
|
-
Authorization: [`Token ${AUTH_PLACEHOLDER_TOKEN}`],
|
|
475
|
-
},
|
|
476
|
-
},
|
|
477
|
-
]);
|
|
478
|
-
const svc = new StubService();
|
|
479
|
-
svc.buildGenerationOptions = () => ({
|
|
480
|
-
traceFilePath: traceFile,
|
|
481
|
-
authHeader: "Authorization",
|
|
482
|
-
authScheme: "Bearer",
|
|
483
|
-
outputDir: "/tmp/tests",
|
|
484
|
-
language: "python",
|
|
485
|
-
framework: "pytest",
|
|
486
|
-
});
|
|
487
|
-
svc.handleApiAnalysis = async () => null;
|
|
488
|
-
await svc.generateTest({ ...BASE });
|
|
489
|
-
const callArgs = mockGenerateRestTest.mock.calls[0][0];
|
|
490
|
-
// authHeader is cleared for Authorization when authType is set (CLI conflict fix)
|
|
491
|
-
expect(callArgs.authHeader).toBeUndefined();
|
|
492
|
-
expect(callArgs.authType).toBe("Token");
|
|
493
|
-
expect(callArgs.authScheme).toBeUndefined();
|
|
494
|
-
});
|
|
495
|
-
it("does not override auth when trace has no auth header (clears Authorization authHeader)", async () => {
|
|
496
|
-
const traceFile = writeTrace([
|
|
497
|
-
{
|
|
498
|
-
RequestHeaders: {
|
|
499
|
-
"Content-Type": ["application/json"],
|
|
500
|
-
},
|
|
501
|
-
},
|
|
502
|
-
]);
|
|
503
|
-
const svc = new StubService();
|
|
504
|
-
svc.buildGenerationOptions = () => ({
|
|
505
|
-
traceFilePath: traceFile,
|
|
506
|
-
authHeader: "Authorization",
|
|
507
|
-
authScheme: "Bearer",
|
|
508
|
-
outputDir: "/tmp/tests",
|
|
509
|
-
language: "python",
|
|
510
|
-
framework: "pytest",
|
|
511
|
-
});
|
|
512
|
-
svc.handleApiAnalysis = async () => null;
|
|
513
|
-
await svc.generateTest({ ...BASE });
|
|
514
|
-
const callArgs = mockGenerateRestTest.mock.calls[0][0];
|
|
515
|
-
// authHeader is cleared for Authorization when authType is set (CLI conflict fix)
|
|
516
|
-
expect(callArgs.authHeader).toBeUndefined();
|
|
517
|
-
expect(callArgs.authType).toBe("Bearer");
|
|
518
|
-
expect(callArgs.authScheme).toBeUndefined();
|
|
519
|
-
});
|
|
520
|
-
});
|
|
521
|
-
describe("TestGenerationService — workspace skipTLSVerify auto-resolve (SKYR-3961)", () => {
|
|
522
|
-
let mockGenerateRestTest;
|
|
523
|
-
let wsDir;
|
|
524
|
-
beforeEach(() => {
|
|
525
|
-
mockGenerateRestTest = jest.fn().mockResolvedValue("Test generation success");
|
|
526
|
-
SkyrampClient.mockImplementation(() => ({
|
|
527
|
-
generateRestTest: mockGenerateRestTest,
|
|
528
|
-
}));
|
|
529
|
-
wsDir = fs.mkdtempSync(path.join(os.tmpdir(), "skyramp-ws-"));
|
|
530
|
-
});
|
|
531
|
-
afterEach(() => {
|
|
532
|
-
fs.rmSync(wsDir, { recursive: true, force: true });
|
|
533
|
-
});
|
|
534
|
-
function writeWorkspace(api) {
|
|
535
|
-
const dir = path.join(wsDir, ".skyramp");
|
|
536
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
537
|
-
fs.writeFileSync(path.join(dir, "workspace.yml"), [
|
|
538
|
-
"workspace:",
|
|
539
|
-
" repoName: org/sut",
|
|
540
|
-
"services:",
|
|
541
|
-
" - serviceName: sut",
|
|
542
|
-
" api:",
|
|
543
|
-
...Object.entries(api).map(([k, v]) => ` ${k}: ${v}`),
|
|
544
|
-
].join("\n"), "utf8");
|
|
545
|
-
}
|
|
546
|
-
it("sets insecure from workspace when the caller did not request it", async () => {
|
|
547
|
-
writeWorkspace({ baseUrl: "https://127.0.0.1:45643", skipTLSVerify: true });
|
|
548
|
-
const svc = new StubService();
|
|
549
|
-
svc.buildGenerationOptions = () => ({
|
|
550
|
-
authHeader: "",
|
|
551
|
-
authScheme: "",
|
|
552
|
-
outputDir: wsDir,
|
|
553
|
-
language: "python",
|
|
554
|
-
framework: "pytest",
|
|
555
|
-
});
|
|
556
|
-
svc.handleApiAnalysis = async () => null;
|
|
557
|
-
await svc.generateTest({ ...BASE });
|
|
558
|
-
const callArgs = mockGenerateRestTest.mock.calls[0][0];
|
|
559
|
-
// generateInsecure is the key SkyrampClient reads (buildBaseGenerationOptions
|
|
560
|
-
// maps the tool param `insecure` onto it).
|
|
561
|
-
expect(callArgs.generateInsecure).toBe(true);
|
|
562
|
-
});
|
|
563
|
-
it("leaves insecure unset when the workspace does not declare it", async () => {
|
|
564
|
-
writeWorkspace({ baseUrl: "https://127.0.0.1:45643" });
|
|
565
|
-
const svc = new StubService();
|
|
566
|
-
svc.buildGenerationOptions = () => ({
|
|
567
|
-
authHeader: "",
|
|
568
|
-
authScheme: "",
|
|
569
|
-
outputDir: wsDir,
|
|
570
|
-
language: "python",
|
|
571
|
-
framework: "pytest",
|
|
572
|
-
});
|
|
573
|
-
svc.handleApiAnalysis = async () => null;
|
|
574
|
-
await svc.generateTest({ ...BASE });
|
|
575
|
-
const callArgs = mockGenerateRestTest.mock.calls[0][0];
|
|
576
|
-
expect(callArgs.generateInsecure).not.toBe(true);
|
|
577
|
-
});
|
|
578
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { TOOL_PHASE_MAP, TOOLS_WITHOUT_PHASE } from "./tool-phases.js";
|
|
2
|
-
import * as fs from "fs";
|
|
3
|
-
import * as path from "path";
|
|
4
|
-
import { fileURLToPath } from "url";
|
|
5
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
-
function findAllToolNames() {
|
|
7
|
-
const toolNames = [];
|
|
8
|
-
function walk(dir) {
|
|
9
|
-
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
10
|
-
const full = path.join(dir, entry.name);
|
|
11
|
-
if (entry.isDirectory()) {
|
|
12
|
-
walk(full);
|
|
13
|
-
continue;
|
|
14
|
-
}
|
|
15
|
-
if (!entry.name.endsWith(".ts"))
|
|
16
|
-
continue;
|
|
17
|
-
const content = fs.readFileSync(full, "utf-8");
|
|
18
|
-
const matches = content.matchAll(/const TOOL_NAME\s*=\s*["']([^"']+)["']/g);
|
|
19
|
-
for (const m of matches)
|
|
20
|
-
toolNames.push(m[1]);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
walk(path.resolve(__dirname, "./tools"));
|
|
24
|
-
return toolNames;
|
|
25
|
-
}
|
|
26
|
-
describe("tool-phase-coverage", () => {
|
|
27
|
-
it("every registered tool has a phase or is explicitly excluded", () => {
|
|
28
|
-
const allTools = findAllToolNames();
|
|
29
|
-
expect(allTools.length).toBeGreaterThan(0);
|
|
30
|
-
const missing = allTools.filter(name => !(name in TOOL_PHASE_MAP) && !TOOLS_WITHOUT_PHASE.has(name));
|
|
31
|
-
if (missing.length > 0) {
|
|
32
|
-
throw new Error(`These tools are not in TOOL_PHASE_MAP or TOOLS_WITHOUT_PHASE in src/tool-phases.ts:\n` +
|
|
33
|
-
missing.map(n => ` - ${n}`).join("\n") +
|
|
34
|
-
`\nAdd them to the appropriate export in src/tool-phases.ts`);
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
it("TOOL_PHASE_MAP contains only valid phases", () => {
|
|
38
|
-
const validPhases = new Set(["analyzing", "generating", "executing", "maintaining", "reporting"]);
|
|
39
|
-
for (const [tool, mapping] of Object.entries(TOOL_PHASE_MAP)) {
|
|
40
|
-
if (typeof mapping === "string") {
|
|
41
|
-
expect(validPhases.has(mapping)).toBe(true);
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
expect(validPhases.has(mapping.before)).toBe(true);
|
|
45
|
-
expect(validPhases.has(mapping.after)).toBe(true);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|