@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.
Files changed (289) hide show
  1. package/build/commands/commandLibrary.d.ts +1 -0
  2. package/build/commands/commandLibrary.js +19 -13
  3. package/build/commands/localDevTestChangesCommand.d.ts +15 -0
  4. package/build/commands/localDevTestChangesCommand.js +201 -0
  5. package/build/index.js +80 -6
  6. package/build/prompts/code-reuse.js +3 -0
  7. package/build/prompts/enhance-assertions/sharedAssertionRules.d.ts +1 -0
  8. package/build/prompts/enhance-assertions/sharedAssertionRules.js +17 -0
  9. package/build/prompts/initialize-workspace/initializeWorkspacePrompt.js +11 -9
  10. package/build/prompts/local-dev/local-dev-plan.d.ts +35 -0
  11. package/build/prompts/local-dev/local-dev-plan.js +429 -0
  12. package/build/prompts/local-dev/local-dev-prompts.d.ts +4 -0
  13. package/build/prompts/local-dev/local-dev-prompts.js +190 -0
  14. package/build/prompts/pom-aware-code-reuse.js +12 -0
  15. package/build/prompts/prompt-utils.d.ts +8 -0
  16. package/build/prompts/prompt-utils.js +33 -0
  17. package/build/prompts/sut-setup/modes/adaptWorkflowPrompt.js +37 -14
  18. package/build/prompts/sut-setup/shared.js +16 -12
  19. package/build/prompts/test-recommendation/analysisOutputPrompt.js +21 -29
  20. package/build/prompts/test-recommendation/scopeAssessment.d.ts +24 -7
  21. package/build/prompts/test-recommendation/scopeAssessment.js +111 -12
  22. package/build/prompts/test-recommendation/test-recommendation-prompt.js +41 -4
  23. package/build/prompts/testbot/testbot-prompts.d.ts +0 -5
  24. package/build/prompts/testbot/testbot-prompts.js +32 -52
  25. package/build/recommendation/planRanker.d.ts +15 -2
  26. package/build/recommendation/planRanker.js +76 -5
  27. package/build/resources/testbotResource.js +2 -1
  28. package/build/services/AnalyticsService.d.ts +1 -1
  29. package/build/services/TestExecutionService.d.ts +2 -1
  30. package/build/services/TestExecutionService.js +8 -3
  31. package/build/services/TestGenerationService.d.ts +2 -2
  32. package/build/services/TestGenerationService.js +39 -21
  33. package/build/services/containerEnv.js +3 -1
  34. package/build/tool-phases.js +6 -0
  35. package/build/tools/code-refactor/codeReuseTool.js +43 -4
  36. package/build/tools/code-refactor/enhanceAssertionsTool.js +68 -18
  37. package/build/tools/code-refactor/reuse-outcome.d.ts +109 -0
  38. package/build/tools/code-refactor/reuse-outcome.js +158 -0
  39. package/build/tools/code-refactor/reuse-state.d.ts +45 -0
  40. package/build/tools/code-refactor/reuse-state.js +140 -0
  41. package/build/tools/enrichTestWithMocksTool.d.ts +28 -0
  42. package/build/tools/enrichTestWithMocksTool.js +726 -0
  43. package/build/tools/executeSkyrampTestTool.d.ts +11 -0
  44. package/build/tools/executeSkyrampTestTool.js +62 -21
  45. package/build/tools/generate-tests/batchMockGenerationTool.d.ts +106 -0
  46. package/build/tools/generate-tests/batchMockGenerationTool.js +545 -0
  47. package/build/tools/generate-tests/generateBatchScenarioRestTool.js +25 -23
  48. package/build/tools/generate-tests/generateContractRestTool.js +2 -2
  49. package/build/tools/generate-tests/generateE2ERestTool.d.ts +1 -1
  50. package/build/tools/generate-tests/generateE2ERestTool.js +1 -1
  51. package/build/tools/generate-tests/generateLoadRestTool.d.ts +1 -1
  52. package/build/tools/generate-tests/generateLoadRestTool.js +1 -1
  53. package/build/tools/generate-tests/generateMockRestTool.d.ts +179 -6
  54. package/build/tools/generate-tests/generateMockRestTool.js +391 -22
  55. package/build/tools/generate-tests/loadTestSchema.d.ts +1 -1
  56. package/build/tools/generate-tests/planGuard.js +2 -22
  57. package/build/tools/generateEnrichedIntegrationTestTool.d.ts +25 -0
  58. package/build/tools/generateEnrichedIntegrationTestTool.js +235 -0
  59. package/build/tools/localDevWorkerComposeTool.d.ts +24 -0
  60. package/build/tools/localDevWorkerComposeTool.js +264 -0
  61. package/build/tools/one-click/oneClickTool.d.ts +13 -0
  62. package/build/tools/one-click/oneClickTool.js +195 -24
  63. package/build/tools/preflightMockCheckTool.d.ts +2 -0
  64. package/build/tools/preflightMockCheckTool.js +96 -0
  65. package/build/tools/queryProxyMocksTool.d.ts +70 -0
  66. package/build/tools/queryProxyMocksTool.js +522 -0
  67. package/build/tools/runExistingTestsTool.d.ts +31 -0
  68. package/build/tools/runExistingTestsTool.js +214 -13
  69. package/build/tools/submitReportTool.js +38 -3
  70. package/build/tools/test-management/analyzeChangesTool.d.ts +2 -1
  71. package/build/tools/test-management/analyzeChangesTool.js +63 -40
  72. package/build/tools/test-management/registerTestPlanTool.js +55 -7
  73. package/build/tools/trace/startTraceCollectionTool.js +3 -3
  74. package/build/types/FrontendIntegration.d.ts +3 -0
  75. package/build/types/FrontendIntegration.js +3 -0
  76. package/build/types/OneClickCommands.d.ts +1 -1
  77. package/build/types/Recommendation.d.ts +20 -0
  78. package/build/types/Recommendation.js +32 -6
  79. package/build/types/RepositoryAnalysis.d.ts +131 -14
  80. package/build/types/RepositoryAnalysis.js +16 -2
  81. package/build/types/ReuseOutcome.d.ts +63 -0
  82. package/build/types/ReuseOutcome.js +33 -0
  83. package/build/types/TestExecution.d.ts +1 -0
  84. package/build/types/TestTypes.d.ts +25 -7
  85. package/build/types/TestTypes.js +22 -6
  86. package/build/types/TestbotReport.d.ts +7 -0
  87. package/build/types/index.d.ts +2 -0
  88. package/build/types/index.js +1 -0
  89. package/build/utils/AnalysisStateManager.d.ts +26 -0
  90. package/build/utils/AnalysisStateManager.js +31 -1
  91. package/build/utils/analyze-openapi.js +18 -1
  92. package/build/utils/branchDiff.d.ts +17 -1
  93. package/build/utils/branchDiff.js +99 -14
  94. package/build/utils/featureFlags.d.ts +31 -0
  95. package/build/utils/featureFlags.js +37 -0
  96. package/build/utils/frontendIntegration.js +8 -1
  97. package/build/utils/grpcMockValidation.d.ts +1 -0
  98. package/build/utils/grpcMockValidation.js +49 -0
  99. package/build/utils/httpMethodValidation.d.ts +4 -0
  100. package/build/utils/httpMethodValidation.js +15 -0
  101. package/build/utils/logger.js +1 -1
  102. package/build/utils/mockCompatibility.d.ts +49 -0
  103. package/build/utils/mockCompatibility.js +82 -0
  104. package/build/utils/pom-scope/pom-files.js +7 -0
  105. package/build/utils/pom-verify/bindings.js +11 -1
  106. package/build/utils/pom-verify/re-exports.d.ts +10 -0
  107. package/build/utils/pom-verify/re-exports.js +61 -0
  108. package/build/utils/pom-verify/resolve.d.ts +4 -1
  109. package/build/utils/pom-verify/resolve.js +7 -4
  110. package/build/utils/pom-verify/verify.d.ts +5 -0
  111. package/build/utils/pom-verify/verify.js +25 -3
  112. package/build/utils/progress.js +10 -5
  113. package/build/utils/proxy-terminal.js +3 -3
  114. package/build/utils/routeParsers.d.ts +3 -9
  115. package/build/utils/routeParsers.js +79 -4
  116. package/build/utils/utils.js +2 -2
  117. package/build/utils/versions.d.ts +4 -3
  118. package/build/utils/versions.js +3 -1
  119. package/build/utils/workspaceAuth.d.ts +46 -0
  120. package/build/utils/workspaceAuth.js +156 -1
  121. package/build/workspace/testSuites.d.ts +2 -1
  122. package/build/workspace/testSuites.js +1 -1
  123. package/build/workspace/workspace.d.ts +108 -32
  124. package/build/workspace/workspace.js +32 -4
  125. package/package.json +5 -2
  126. package/build/adapters/jestAdapter.test.d.ts +0 -1
  127. package/build/adapters/jestAdapter.test.js +0 -93
  128. package/build/adapters/mochaAdapter.test.d.ts +0 -1
  129. package/build/adapters/mochaAdapter.test.js +0 -63
  130. package/build/adapters/playwrightAdapter.test.d.ts +0 -1
  131. package/build/adapters/playwrightAdapter.test.js +0 -169
  132. package/build/adapters/pytestAdapter.test.d.ts +0 -1
  133. package/build/adapters/pytestAdapter.test.js +0 -90
  134. package/build/prompts/code-reuse.test.d.ts +0 -1
  135. package/build/prompts/code-reuse.test.js +0 -62
  136. package/build/prompts/pom-aware-code-reuse.test.d.ts +0 -1
  137. package/build/prompts/pom-aware-code-reuse.test.js +0 -11
  138. package/build/prompts/test-maintenance/drift-analysis-prompt.test.d.ts +0 -1
  139. package/build/prompts/test-maintenance/drift-analysis-prompt.test.js +0 -51
  140. package/build/prompts/test-recommendation/analysisOutputPrompt.test.d.ts +0 -1
  141. package/build/prompts/test-recommendation/analysisOutputPrompt.test.js +0 -264
  142. package/build/prompts/test-recommendation/mergeEnrichedScenarios.test.d.ts +0 -1
  143. package/build/prompts/test-recommendation/mergeEnrichedScenarios.test.js +0 -126
  144. package/build/prompts/test-recommendation/promptPlan.test.d.ts +0 -1
  145. package/build/prompts/test-recommendation/promptPlan.test.js +0 -336
  146. package/build/prompts/test-recommendation/scopeAssessment.test.d.ts +0 -1
  147. package/build/prompts/test-recommendation/scopeAssessment.test.js +0 -371
  148. package/build/prompts/test-recommendation/test-recommendation-prompt.test.d.ts +0 -1
  149. package/build/prompts/test-recommendation/test-recommendation-prompt.test.js +0 -1925
  150. package/build/prompts/testbot/testbot-prompts.test.d.ts +0 -1
  151. package/build/prompts/testbot/testbot-prompts.test.js +0 -451
  152. package/build/recommendation/budgeters/diversityBalancedBudgeter.test.d.ts +0 -1
  153. package/build/recommendation/budgeters/diversityBalancedBudgeter.test.js +0 -138
  154. package/build/recommendation/budgeters/fixedNBudgeter.test.d.ts +0 -1
  155. package/build/recommendation/budgeters/fixedNBudgeter.test.js +0 -66
  156. package/build/recommendation/discriminators.test.d.ts +0 -1
  157. package/build/recommendation/discriminators.test.js +0 -324
  158. package/build/recommendation/diversity.test.d.ts +0 -1
  159. package/build/recommendation/diversity.test.js +0 -77
  160. package/build/recommendation/planRanker.test.d.ts +0 -1
  161. package/build/recommendation/planRanker.test.js +0 -110
  162. package/build/resources/testbotResource.test.d.ts +0 -1
  163. package/build/resources/testbotResource.test.js +0 -44
  164. package/build/services/AnalyticsService.test.d.ts +0 -1
  165. package/build/services/AnalyticsService.test.js +0 -86
  166. package/build/services/ScenarioGenerationService.integration.test.d.ts +0 -1
  167. package/build/services/ScenarioGenerationService.integration.test.js +0 -162
  168. package/build/services/ScenarioGenerationService.test.d.ts +0 -1
  169. package/build/services/ScenarioGenerationService.test.js +0 -414
  170. package/build/services/TestDiscoveryService.test.d.ts +0 -1
  171. package/build/services/TestDiscoveryService.test.js +0 -983
  172. package/build/services/TestExecutionService.test.d.ts +0 -1
  173. package/build/services/TestExecutionService.test.js +0 -1032
  174. package/build/services/TestGenerationService.test.d.ts +0 -1
  175. package/build/services/TestGenerationService.test.js +0 -578
  176. package/build/tool-phase-coverage.test.d.ts +0 -1
  177. package/build/tool-phase-coverage.test.js +0 -49
  178. package/build/tools/code-refactor/codeReuseTool.test.d.ts +0 -1
  179. package/build/tools/code-refactor/codeReuseTool.test.js +0 -572
  180. package/build/tools/generate-tests/generateBatchScenarioRestTool.test.d.ts +0 -1
  181. package/build/tools/generate-tests/generateBatchScenarioRestTool.test.js +0 -433
  182. package/build/tools/generate-tests/generateContractRestTool.test.d.ts +0 -1
  183. package/build/tools/generate-tests/generateContractRestTool.test.js +0 -142
  184. package/build/tools/generate-tests/generateIntegrationRestTool.test.d.ts +0 -1
  185. package/build/tools/generate-tests/generateIntegrationRestTool.test.js +0 -159
  186. package/build/tools/generate-tests/generateLoadRestTool.test.d.ts +0 -1
  187. package/build/tools/generate-tests/generateLoadRestTool.test.js +0 -169
  188. package/build/tools/generate-tests/generateUIRestTool.test.d.ts +0 -1
  189. package/build/tools/generate-tests/generateUIRestTool.test.js +0 -32
  190. package/build/tools/generate-tests/planGuard.test.d.ts +0 -1
  191. package/build/tools/generate-tests/planGuard.test.js +0 -185
  192. package/build/tools/generate-tests/scenarioLint.test.d.ts +0 -1
  193. package/build/tools/generate-tests/scenarioLint.test.js +0 -100
  194. package/build/tools/runExistingTestsTool.test.d.ts +0 -1
  195. package/build/tools/runExistingTestsTool.test.js +0 -379
  196. package/build/tools/submitReportTool.test.d.ts +0 -1
  197. package/build/tools/submitReportTool.test.js +0 -1428
  198. package/build/tools/test-management/actionsTool.test.d.ts +0 -1
  199. package/build/tools/test-management/actionsTool.test.js +0 -436
  200. package/build/tools/test-management/analyzeChangesTool.test.d.ts +0 -1
  201. package/build/tools/test-management/analyzeChangesTool.test.js +0 -522
  202. package/build/tools/test-management/analyzeTestHealthTool.test.d.ts +0 -1
  203. package/build/tools/test-management/analyzeTestHealthTool.test.js +0 -385
  204. package/build/tools/test-management/registerTestPlanTool.test.d.ts +0 -1
  205. package/build/tools/test-management/registerTestPlanTool.test.js +0 -296
  206. package/build/tools/trace/resolveSaveStoragePath.test.d.ts +0 -1
  207. package/build/tools/trace/resolveSaveStoragePath.test.js +0 -17
  208. package/build/tools/trace/resolveSessionPaths.test.d.ts +0 -1
  209. package/build/tools/trace/resolveSessionPaths.test.js +0 -104
  210. package/build/tools/trace/sessionState.test.d.ts +0 -1
  211. package/build/tools/trace/sessionState.test.js +0 -17
  212. package/build/tools/workspace/initializeWorkspaceTool.test.d.ts +0 -1
  213. package/build/tools/workspace/initializeWorkspaceTool.test.js +0 -139
  214. package/build/tools/workspace/serviceUpsert.test.d.ts +0 -1
  215. package/build/tools/workspace/serviceUpsert.test.js +0 -50
  216. package/build/utils/AnalysisStateManager.test.d.ts +0 -1
  217. package/build/utils/AnalysisStateManager.test.js +0 -134
  218. package/build/utils/dartRouteExtractor.test.d.ts +0 -1
  219. package/build/utils/dartRouteExtractor.test.js +0 -307
  220. package/build/utils/docker.test.d.ts +0 -1
  221. package/build/utils/docker.test.js +0 -114
  222. package/build/utils/featureFlags.test.d.ts +0 -1
  223. package/build/utils/featureFlags.test.js +0 -81
  224. package/build/utils/fileWalk.test.d.ts +0 -1
  225. package/build/utils/fileWalk.test.js +0 -252
  226. package/build/utils/frontendIntegration.test.d.ts +0 -1
  227. package/build/utils/frontendIntegration.test.js +0 -229
  228. package/build/utils/frontendSelectors.test.d.ts +0 -1
  229. package/build/utils/frontendSelectors.test.js +0 -118
  230. package/build/utils/gitStaging.test.d.ts +0 -1
  231. package/build/utils/gitStaging.test.js +0 -111
  232. package/build/utils/httpDefaults.test.d.ts +0 -1
  233. package/build/utils/httpDefaults.test.js +0 -21
  234. package/build/utils/importerHop.test.d.ts +0 -1
  235. package/build/utils/importerHop.test.js +0 -469
  236. package/build/utils/pathAffinityClassification.test.d.ts +0 -1
  237. package/build/utils/pathAffinityClassification.test.js +0 -208
  238. package/build/utils/planMatchKeys.test.d.ts +0 -1
  239. package/build/utils/planMatchKeys.test.js +0 -123
  240. package/build/utils/pom-scope/index.test.d.ts +0 -1
  241. package/build/utils/pom-scope/index.test.js +0 -278
  242. package/build/utils/pom-scope/pom-files.test.d.ts +0 -1
  243. package/build/utils/pom-scope/pom-files.test.js +0 -29
  244. package/build/utils/pom-scope/scoring.test.d.ts +0 -1
  245. package/build/utils/pom-scope/scoring.test.js +0 -39
  246. package/build/utils/pom-scope/selector-extractor.test.d.ts +0 -1
  247. package/build/utils/pom-scope/selector-extractor.test.js +0 -67
  248. package/build/utils/pom-verify/bindings.test.d.ts +0 -1
  249. package/build/utils/pom-verify/bindings.test.js +0 -164
  250. package/build/utils/pom-verify/calls.test.d.ts +0 -1
  251. package/build/utils/pom-verify/calls.test.js +0 -61
  252. package/build/utils/pom-verify/resolve.test.d.ts +0 -1
  253. package/build/utils/pom-verify/resolve.test.js +0 -114
  254. package/build/utils/pom-verify/verify.test.d.ts +0 -1
  255. package/build/utils/pom-verify/verify.test.js +0 -374
  256. package/build/utils/pr-comment-parser.test.d.ts +0 -1
  257. package/build/utils/pr-comment-parser.test.js +0 -428
  258. package/build/utils/progress.test.d.ts +0 -1
  259. package/build/utils/progress.test.js +0 -37
  260. package/build/utils/projectMetadata.test.d.ts +0 -1
  261. package/build/utils/projectMetadata.test.js +0 -172
  262. package/build/utils/pythonMountPrefixes.test.d.ts +0 -1
  263. package/build/utils/pythonMountPrefixes.test.js +0 -113
  264. package/build/utils/repoScanner.test.d.ts +0 -1
  265. package/build/utils/repoScanner.test.js +0 -190
  266. package/build/utils/reportVerification.test.d.ts +0 -1
  267. package/build/utils/reportVerification.test.js +0 -185
  268. package/build/utils/routeParsers.test.d.ts +0 -1
  269. package/build/utils/routeParsers.test.js +0 -1011
  270. package/build/utils/scenarioDrafting.test.d.ts +0 -1
  271. package/build/utils/scenarioDrafting.test.js +0 -876
  272. package/build/utils/sourceRouteExtractor.test.d.ts +0 -1
  273. package/build/utils/sourceRouteExtractor.test.js +0 -738
  274. package/build/utils/telemetry.test.d.ts +0 -1
  275. package/build/utils/telemetry.test.js +0 -70
  276. package/build/utils/trace-parser.test.d.ts +0 -6
  277. package/build/utils/trace-parser.test.js +0 -140
  278. package/build/utils/uiPageEnumerator.test.d.ts +0 -1
  279. package/build/utils/uiPageEnumerator.test.js +0 -824
  280. package/build/utils/utils.test.d.ts +0 -1
  281. package/build/utils/utils.test.js +0 -103
  282. package/build/utils/walkerCharacterization.test.d.ts +0 -1
  283. package/build/utils/walkerCharacterization.test.js +0 -233
  284. package/build/utils/workspaceAuth.test.d.ts +0 -1
  285. package/build/utils/workspaceAuth.test.js +0 -260
  286. package/build/workspace/testSuites.test.d.ts +0 -1
  287. package/build/workspace/testSuites.test.js +0 -23
  288. package/build/workspace/workspace.test.d.ts +0 -1
  289. package/build/workspace/workspace.test.js +0 -264
@@ -1,39 +0,0 @@
1
- import * as path from "path";
2
- import { fileURLToPath } from "url";
3
- import { globPomFiles } from "./pom-files.js";
4
- import { scorePoms } from "./scoring.js";
5
- const FIX = path.join(path.dirname(fileURLToPath(import.meta.url)), "__fixtures__");
6
- describe("scorePoms", () => {
7
- it("ranks rare-selector files high; ubiquitous selectors contribute ~nothing", async () => {
8
- const files = await globPomFiles(FIX);
9
- // widget-add-btn appears only in widgetsPage (df=1) → strong.
10
- // o-toast-message appears in 3 files (df=3) → weak-ish but still rare in this tiny fixture;
11
- // login-sign-in only in loginPage (df=1) → strong.
12
- const ranked = await scorePoms(["widget-add-btn", "login-sign-in", "o-toast-message"], files);
13
- const names = ranked.map((r) => path.basename(r.file));
14
- expect(names[0]).toBe("widgetsPage.js"); // 1/1 + 1/3
15
- expect(names[1]).toBe("loginPage.js"); // 1/1 + 1/3
16
- const toastOnly = ranked.find((r) => path.basename(r.file) === "toastPage.js");
17
- expect(toastOnly.score).toBeLessThan(0.5); // only the shared toast selector
18
- expect(toastOnly.rareHits).toBeGreaterThanOrEqual(0);
19
- });
20
- it("matches through backslash escaping", async () => {
21
- const files = await globPomFiles(FIX);
22
- // fixture loginPage has plain value; simulate escaped token from spec
23
- const ranked = await scorePoms(["login-sign-in"], files);
24
- expect(path.basename(ranked[0].file)).toBe("loginPage.js");
25
- expect(ranked[0].hits).toBe(1);
26
- });
27
- it("returns empty for no selectors or no files", async () => {
28
- expect(await scorePoms([], ["x"])).toEqual([]);
29
- expect(await scorePoms(["a-b-c"], [])).toEqual([]);
30
- });
31
- it("records which tokens matched each file", async () => {
32
- const files = await globPomFiles(FIX);
33
- const ranked = await scorePoms(["widget-add-btn", "o-toast-message"], files);
34
- const widgets = ranked.find((r) => path.basename(r.file) === "widgetsPage.js");
35
- expect(widgets.matchedTokens).toEqual(["widget-add-btn", "o-toast-message"]);
36
- const toast = ranked.find((r) => path.basename(r.file) === "toastPage.js");
37
- expect(toast.matchedTokens).toEqual(["o-toast-message"]);
38
- });
39
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,67 +0,0 @@
1
- import { extractSelectors } from "./selector-extractor.js";
2
- describe("extractSelectors", () => {
3
- it("extracts data-test attribute values", () => {
4
- const spec = `await page.locator("[data-test=\\"login-sign-in\\"]").click();
5
- await page.locator('[data-test="add-template-name-input-field"]').fill("x");`;
6
- const t = extractSelectors(spec);
7
- expect(t).toContain("login-sign-in");
8
- expect(t).toContain("add-template-name-input-field");
9
- });
10
- it("extracts getByTestId / getByRole / getByText tokens", () => {
11
- const spec = `page.getByTestId("tpl-add");
12
- page.getByRole("button", { name: "Save Template" });
13
- page.getByText("Templates");`;
14
- const t = extractSelectors(spec);
15
- expect(t).toEqual(expect.arrayContaining(["tpl-add", "button", "Save Template", "Templates"]));
16
- });
17
- it("normalizes escaped slashes and dedupes", () => {
18
- const spec = `page.locator("[data-test=\\"menu-link-\\\\/alerts-item\\"]");
19
- page.locator('[data-test="menu-link-/alerts-item"]');`;
20
- const t = extractSelectors(spec);
21
- expect(t.filter((x) => x === "menu-link-/alerts-item")).toHaveLength(1);
22
- expect(t).not.toContain("menu-link-");
23
- });
24
- it("extracts values from prefix/suffix data-test matchers", () => {
25
- const spec = `page.locator('[data-test^="ai-integrations-item-"]'); page.locator('[data-test*="row-cell"]');`;
26
- const t = extractSelectors(spec);
27
- expect(t).toEqual(expect.arrayContaining(["ai-integrations-item-", "row-cell"]));
28
- });
29
- it("keeps non-data-test raw locator strings, drops short/numeric tokens", () => {
30
- const spec = `page.locator(".step-deduplication"); page.locator("#a"); page.getByText("42");`;
31
- const t = extractSelectors(spec);
32
- expect(t).toContain(".step-deduplication");
33
- expect(t).not.toContain("#a");
34
- expect(t).not.toContain("42");
35
- });
36
- it("returns [] for content with no selectors", () => {
37
- expect(extractSelectors("const x = 1;")).toEqual([]);
38
- });
39
- it("matches the test-id attribute family (data-testid default, data-qa, data-cy)", () => {
40
- const spec = `page.locator('[data-testid="submit-order"]'); page.locator('[data-qa="cart-total"]'); page.locator('[data-cy="nav-home"]');`;
41
- const t = extractSelectors(spec);
42
- expect(t).toEqual(expect.arrayContaining(["submit-order", "cart-total", "nav-home"]));
43
- });
44
- it("accepts extra custom attributes", () => {
45
- const t = extractSelectors(`page.locator('[data-pw="widget-x"]');`, ["data-pw"]);
46
- expect(t).toContain("widget-x");
47
- });
48
- it("keeps raw css locators that merely contain a family-attr substring", () => {
49
- const t = extractSelectors(`page.locator(".data-testing-notes"); page.locator(".data-qatar-widget"); page.locator(".data-cycle-indicator");`);
50
- expect(t).toEqual(expect.arrayContaining([".data-testing-notes", ".data-qatar-widget", ".data-cycle-indicator"]));
51
- });
52
- it("matches locator strings containing the other quote type (has-text idiom)", () => {
53
- const spec = `page.locator('button:has-text("資産登録")'); page.locator("li:has-text('確認')");`;
54
- const t = extractSelectors(spec);
55
- expect(t).toEqual(expect.arrayContaining(['button:has-text("資産登録")', "li:has-text('確認')"]));
56
- });
57
- it("still dedups bracketed test-id raw locators regardless of quote nesting", () => {
58
- const t = extractSelectors(`page.locator('[data-test="pay-now"]');`);
59
- expect(t).toEqual(["pay-now"]); // attribute value only — raw form still skipped
60
- });
61
- it("extracts frameLocator selector args (iframe-scoped POM evidence)", () => {
62
- const spec = `page.frameLocator('iframe#asset-list').locator('button:has-text("資産登録")').click();
63
- page.frameLocator("#application-new-applied").getByRole("button", { name: "提出" });`;
64
- const t = extractSelectors(spec);
65
- expect(t).toEqual(expect.arrayContaining(["iframe#asset-list", "#application-new-applied", 'button:has-text("資産登録")']));
66
- });
67
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,164 +0,0 @@
1
- import * as path from "path";
2
- import { fileURLToPath } from "url";
3
- import { extractPomBindings } from "./bindings.js";
4
- const OO = path.join(path.dirname(fileURLToPath(import.meta.url)), "__fixtures__", "oo-style");
5
- const AF = path.join(path.dirname(fileURLToPath(import.meta.url)), "__fixtures__", "af-style");
6
- const OO_POM_FILES = [
7
- path.join(OO, "page-manager.js"),
8
- path.join(OO, "loginPage.js"),
9
- path.join(OO, "widgetsPage.js"),
10
- path.join(OO, "widgetHelpers.js"),
11
- path.join(OO, "commonActions.js"),
12
- ];
13
- const AF_POM_FILES = [
14
- path.join(AF, "asset-list.page.ts"),
15
- path.join(AF, "workflow-footer.page.ts"),
16
- path.join(AF, "report.iframe.page.ts"),
17
- ];
18
- describe("extractPomBindings -- oo-style (page-manager convention)", () => {
19
- it("binds every <pm>.<member> when the spec instantiates the page manager", async () => {
20
- const spec = `
21
- import { PageManager } from './page-manager.js';
22
- const pm = new PageManager(page);
23
- await pm.loginPage.signIn.click();
24
- `;
25
- const { bindings, unrecognized } = await extractPomBindings(spec, {
26
- specDir: OO,
27
- pomFiles: OO_POM_FILES,
28
- pageManagerFile: path.join(OO, "page-manager.js"),
29
- });
30
- expect(bindings).toEqual(expect.arrayContaining([
31
- { kind: "instance", name: "pm.loginPage", classFile: path.join(OO, "loginPage.js") },
32
- { kind: "instance", name: "pm.widgetsPage", classFile: path.join(OO, "widgetsPage.js") },
33
- ]));
34
- expect(unrecognized).toEqual([]);
35
- });
36
- it("flags an unknown page-manager member as unrecognized instead of fabricating a binding", async () => {
37
- const spec = `
38
- import { PageManager } from './page-manager.js';
39
- const pm = new PageManager(page);
40
- await pm.reportsPage.export();
41
- `;
42
- const { bindings, unrecognized } = await extractPomBindings(spec, {
43
- specDir: OO,
44
- pomFiles: OO_POM_FILES,
45
- pageManagerFile: path.join(OO, "page-manager.js"),
46
- });
47
- expect(bindings.some((b) => b.name.includes("reportsPage"))).toBe(false);
48
- expect(unrecognized).toContain("pm.reportsPage");
49
- });
50
- it("binds a direct `new` instantiation of an imported POM class (no page manager)", async () => {
51
- const spec = `
52
- import { LoginPage } from './loginPage.js';
53
- const login = new LoginPage(page);
54
- await login.signIn.click();
55
- `;
56
- const { bindings, unrecognized } = await extractPomBindings(spec, { specDir: OO, pomFiles: OO_POM_FILES });
57
- expect(bindings).toEqual([{ kind: "instance", name: "login", classFile: path.join(OO, "loginPage.js") }]);
58
- expect(unrecognized).toEqual([]);
59
- });
60
- it("binds an imported free function used as a direct call", async () => {
61
- const spec = `
62
- import { openNavFlyout } from './commonActions.js';
63
- await openNavFlyout(page);
64
- `;
65
- const { bindings, unrecognized } = await extractPomBindings(spec, { specDir: OO, pomFiles: OO_POM_FILES });
66
- expect(bindings).toEqual([{ kind: "function", name: "openNavFlyout", sourceFile: path.join(OO, "commonActions.js") }]);
67
- expect(unrecognized).toEqual([]);
68
- });
69
- it("never fabricates a binding for `new` on an import that isn't a recognized POM file", async () => {
70
- const spec = `
71
- import { HelperNonPom } from './helperNonPom.js';
72
- const helper = new HelperNonPom();
73
- `;
74
- // helperNonPom.js intentionally excluded from pomFiles -- it's a non-POM utility.
75
- const { bindings, unrecognized } = await extractPomBindings(spec, { specDir: OO, pomFiles: OO_POM_FILES });
76
- expect(bindings).toEqual([]);
77
- expect(unrecognized).toContain("helper");
78
- });
79
- it("ignores commented-out import/new/call syntax instead of fabricating a binding from it", async () => {
80
- const spec = `
81
- // import { LoginPage } from './loginPage.js'; const login = new LoginPage(page);
82
- /* const helper2 = new LoginPage(page); */
83
- const note = "import { LoginPage } from './loginPage.js'; const login2 = new LoginPage(page);";
84
- import { openNavFlyout } from './commonActions.js';
85
- // await openNavFlyout(page);
86
- `;
87
- const { bindings, unrecognized } = await extractPomBindings(spec, { specDir: OO, pomFiles: OO_POM_FILES });
88
- expect(bindings).toEqual([]);
89
- expect(unrecognized).toEqual([]);
90
- });
91
- });
92
- describe("extractPomBindings -- oo-style (CJS page-manager convention)", () => {
93
- it("binds pm.<member> from a page-manager file with no `export` on its class, a default import, and an extensionless require -- the real oo-testbed shape", async () => {
94
- const spec = `
95
- const PageManager = require('./page-manager-cjs.js');
96
- const pm = new PageManager(page);
97
- await pm.loginPage.signInAs(user);
98
- await pm.widgetsPage.toggle('foo');
99
- `;
100
- const { bindings, unrecognized } = await extractPomBindings(spec, {
101
- specDir: OO,
102
- pomFiles: [...OO_POM_FILES, path.join(OO, "page-manager-cjs.js")],
103
- pageManagerFile: path.join(OO, "page-manager-cjs.js"),
104
- });
105
- expect(bindings).toEqual(expect.arrayContaining([
106
- { kind: "instance", name: "pm.loginPage", classFile: path.join(OO, "loginPage.js") },
107
- { kind: "instance", name: "pm.widgetsPage", classFile: path.join(OO, "widgetsPage.js") },
108
- ]));
109
- expect(unrecognized).toEqual([]);
110
- });
111
- });
112
- describe("extractPomBindings -- alias-import resolution", () => {
113
- const AF_PAGEOBJECTS = path.join(AF, "pageobjects");
114
- const ASSET_LIST_ALIAS_FILE = path.join(AF_PAGEOBJECTS, "asset-list-page.ts");
115
- it("resolves a non-relative specifier through aliasMap when the target is a recognized POM file", async () => {
116
- const spec = `
117
- import { AssetListPage } from '@pageobjects/asset-list-page';
118
- const list = new AssetListPage(page);
119
- await list.clickSearch();
120
- `;
121
- const { bindings, unrecognized } = await extractPomBindings(spec, {
122
- specDir: AF,
123
- pomFiles: [ASSET_LIST_ALIAS_FILE],
124
- aliasMap: { "@pageobjects": AF_PAGEOBJECTS },
125
- });
126
- expect(bindings).toEqual([{ kind: "instance", name: "list", classFile: ASSET_LIST_ALIAS_FILE }]);
127
- expect(unrecognized).toEqual([]);
128
- });
129
- it("never fabricates a binding through an alias when the resolved file isn't in pomFiles (safety contract)", async () => {
130
- const spec = `
131
- import { AssetListPage } from '@pageobjects/asset-list-page';
132
- const list = new AssetListPage(page);
133
- `;
134
- const { bindings, unrecognized } = await extractPomBindings(spec, {
135
- specDir: AF,
136
- pomFiles: [], // asset-list-page.ts intentionally excluded
137
- aliasMap: { "@pageobjects": AF_PAGEOBJECTS },
138
- });
139
- expect(bindings).toEqual([]);
140
- expect(unrecognized).toContain("list");
141
- });
142
- });
143
- describe("extractPomBindings -- af-style (direct instantiation)", () => {
144
- it("binds a direct-instantiation class with a component property chain", async () => {
145
- const spec = `
146
- import { AssetListPage } from './asset-list.page.js';
147
- const list = new AssetListPage(page);
148
- await list.footer.okBtn.click();
149
- `;
150
- const { bindings, unrecognized } = await extractPomBindings(spec, { specDir: AF, pomFiles: AF_POM_FILES });
151
- expect(bindings).toEqual([{ kind: "instance", name: "list", classFile: path.join(AF, "asset-list.page.ts") }]);
152
- expect(unrecognized).toEqual([]);
153
- });
154
- it("binds a direct-instantiation iframe-scoped class the same way", async () => {
155
- const spec = `
156
- import { ReportIframePage } from './report.iframe.page.js';
157
- const report = new ReportIframePage(frame);
158
- await report.exportBtn.click();
159
- `;
160
- const { bindings, unrecognized } = await extractPomBindings(spec, { specDir: AF, pomFiles: AF_POM_FILES });
161
- expect(bindings).toEqual([{ kind: "instance", name: "report", classFile: path.join(AF, "report.iframe.page.ts") }]);
162
- expect(unrecognized).toEqual([]);
163
- });
164
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,61 +0,0 @@
1
- import { extractPomCalls } from "./calls.js";
2
- describe("extractPomCalls -- oo-style", () => {
3
- const loginBinding = { kind: "instance", name: "login", classFile: "/fake/loginPage.js" };
4
- const fnBinding = { kind: "function", name: "openNavFlyout", sourceFile: "/fake/commonActions.js" };
5
- it("first-hop method call -> strict:true", () => {
6
- const spec = `await login.signInAs(user);`;
7
- expect(extractPomCalls(spec, [loginBinding])).toEqual([{ binding: "login", chain: ["signInAs"], strict: true }]);
8
- });
9
- it("property-only use (e.g. inside expect()) counts as a call too", () => {
10
- const spec = `expect(login.toast).toBeVisible();`;
11
- expect(extractPomCalls(spec, [loginBinding])).toEqual([{ binding: "login", chain: ["toast"], strict: true }]);
12
- });
13
- it("chains beyond the first hop are strict:false", () => {
14
- const spec = `await login.signIn.click();`;
15
- expect(extractPomCalls(spec, [loginBinding])).toEqual([{ binding: "login", chain: ["signIn", "click"], strict: false }]);
16
- });
17
- it("a free-function binding's direct call has an empty chain and is strict", () => {
18
- const spec = `await openNavFlyout(page);`;
19
- expect(extractPomCalls(spec, [fnBinding])).toEqual([{ binding: "openNavFlyout", chain: [], strict: true }]);
20
- });
21
- it("dedupes identical (binding, chain) occurrences", () => {
22
- const spec = `
23
- await login.signIn.click();
24
- await login.signIn.click();
25
- `;
26
- expect(extractPomCalls(spec, [loginBinding])).toEqual([{ binding: "login", chain: ["signIn", "click"], strict: false }]);
27
- });
28
- it("a page-manager-style dotted binding name doesn't double-count against a shorter binding sharing its suffix", () => {
29
- const pmLoginBinding = { kind: "instance", name: "pm.loginPage", classFile: "/fake/loginPage.js" };
30
- const plainLoginBinding = { kind: "instance", name: "loginPage", classFile: "/fake/loginPage.js" };
31
- const spec = `await pm.loginPage.signIn.click();`;
32
- const calls = extractPomCalls(spec, [pmLoginBinding, plainLoginBinding]);
33
- expect(calls).toEqual([{ binding: "pm.loginPage", chain: ["signIn", "click"], strict: false }]);
34
- });
35
- it("does not let quotes inside regex literals swallow real code", () => {
36
- const spec = `page.getByText(/Don't have an account/).click();\nawait login.signIn.click();\nawait login.logout();`;
37
- const calls = extractPomCalls(spec, [{ kind: "instance", name: "login", classFile: "/x/login.js" }]);
38
- expect(calls).toEqual(expect.arrayContaining([
39
- { binding: "login", chain: ["signIn", "click"], strict: false },
40
- { binding: "login", chain: ["logout"], strict: true },
41
- ]));
42
- });
43
- it("ignores calls appearing in comments and string/template literals", () => {
44
- const spec = `// setup: login.signIn.click() manually
45
- /* login.signIn.click() */
46
- const doc = "call login.signIn.click()";
47
- const t = \`use login.signIn.click()\`;
48
- login.realCall();`;
49
- const calls = extractPomCalls(spec, [{ kind: "instance", name: "login", classFile: "/x/login.js" }]);
50
- expect(calls).toEqual([{ binding: "login", chain: ["realCall"], strict: true }]);
51
- });
52
- });
53
- describe("extractPomCalls -- af-style", () => {
54
- it("a deep component-property chain (list.footer.okBtn) is strict:false", () => {
55
- const listBinding = { kind: "instance", name: "list", classFile: "/fake/asset-list.page.ts" };
56
- const spec = `await list.footer.okBtn.click();`;
57
- expect(extractPomCalls(spec, [listBinding])).toEqual([
58
- { binding: "list", chain: ["footer", "okBtn", "click"], strict: false },
59
- ]);
60
- });
61
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,114 +0,0 @@
1
- import * as fs from "fs";
2
- import * as os from "os";
3
- import * as path from "path";
4
- import { fileURLToPath } from "url";
5
- import { resolveMemberSource } from "./resolve.js";
6
- const OO = path.join(path.dirname(fileURLToPath(import.meta.url)), "__fixtures__", "oo-style");
7
- const AF = path.join(path.dirname(fileURLToPath(import.meta.url)), "__fixtures__", "af-style");
8
- const OO_POM_FILES = [
9
- path.join(OO, "page-manager.js"),
10
- path.join(OO, "loginPage.js"),
11
- path.join(OO, "widgetsPage.js"),
12
- path.join(OO, "widgetHelpers.js"),
13
- path.join(OO, "commonActions.js"),
14
- ];
15
- const AF_POM_FILES = [
16
- path.join(AF, "asset-list.page.ts"),
17
- path.join(AF, "workflow-footer.page.ts"),
18
- path.join(AF, "report.iframe.page.ts"),
19
- ];
20
- describe("resolveMemberSource -- oo-style", () => {
21
- it("finds a member defined directly in the binding's own class file", async () => {
22
- const binding = { kind: "instance", name: "login", classFile: path.join(OO, "loginPage.js") };
23
- const result = await resolveMemberSource(binding, "signInAs", OO_POM_FILES);
24
- expect(result).toEqual({ found: true, searched: [path.join(OO, "loginPage.js")] });
25
- });
26
- it("falls through to a one-hop imported submodule when the member isn't in the class file itself", async () => {
27
- // "dragWidget" is defined only in widgetHelpers.js -- widgetsPage.js neither imports nor
28
- // mentions it, so a hit here can only come from the one-hop expansion, not the primary file.
29
- const binding = { kind: "instance", name: "widgets", classFile: path.join(OO, "widgetsPage.js") };
30
- const result = await resolveMemberSource(binding, "dragWidget", OO_POM_FILES);
31
- expect(result.found).toBe(true);
32
- expect(result.searched).toEqual([path.join(OO, "widgetsPage.js"), path.join(OO, "widgetHelpers.js")]);
33
- });
34
- it("resolves a free-function binding directly in its source file", async () => {
35
- const binding = { kind: "function", name: "openNavFlyout", sourceFile: path.join(OO, "commonActions.js") };
36
- const result = await resolveMemberSource(binding, "openNavFlyout", OO_POM_FILES);
37
- expect(result).toEqual({ found: true, searched: [path.join(OO, "commonActions.js")] });
38
- });
39
- it("reports not-found with the full searched list when the member exists nowhere", async () => {
40
- const binding = { kind: "instance", name: "login", classFile: path.join(OO, "loginPage.js") };
41
- const result = await resolveMemberSource(binding, "doesNotExistAnywhere", OO_POM_FILES);
42
- expect(result.found).toBe(false);
43
- expect(result.searched).toContain(path.join(OO, "loginPage.js"));
44
- });
45
- });
46
- describe("resolveMemberSource -- comment stripping", () => {
47
- it("does not count a member name that appears only in a comment", async () => {
48
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), "pom-resolve-comment-"));
49
- try {
50
- const file = path.join(dir, "widgetsPage.js");
51
- fs.writeFileSync(file, `// TODO: add dragWidget\nexport class WidgetsPage {}\n`);
52
- const binding = { kind: "instance", name: "widgets", classFile: file };
53
- const result = await resolveMemberSource(binding, "dragWidget", [file]);
54
- expect(result).toEqual({ found: false, searched: [file] });
55
- }
56
- finally {
57
- fs.rmSync(dir, { recursive: true, force: true });
58
- }
59
- });
60
- });
61
- describe("resolveMemberSource -- definition-shape matching (not a bare token match)", () => {
62
- it("does NOT count a local variable/parameter that merely shares the hallucinated member's name", async () => {
63
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), "pom-resolve-mask-"));
64
- try {
65
- const file = path.join(dir, "widgetsPage.js");
66
- fs.writeFileSync(file, `export class WidgetsPage {\n` +
67
- ` constructor(page) {\n` +
68
- ` const dragWidget = 5;\n` +
69
- ` this.page = page;\n` +
70
- ` }\n` +
71
- ` use(dragWidget) {\n` +
72
- ` return dragWidget;\n` +
73
- ` }\n` +
74
- `}\n`);
75
- const binding = { kind: "instance", name: "widgets", classFile: file };
76
- const result = await resolveMemberSource(binding, "dragWidget", [file]);
77
- expect(result).toEqual({ found: false, searched: [file] });
78
- }
79
- finally {
80
- fs.rmSync(dir, { recursive: true, force: true });
81
- }
82
- });
83
- it.each([
84
- ["method (multi-line, indented)", `class Foo {\n bar() {\n return 1;\n }\n}\n`, "bar"],
85
- ["method (single-line/minified class body)", `export class Foo { ctor(){ } bar(){ return 1; } }`, "bar"],
86
- ["property assignment", `class Foo { constructor(){ this.baz = 1; } }`, "baz"],
87
- ["getter", `class Foo { get qux() { return 1; } }`, "qux"],
88
- ["setter", `class Foo { set qux(v) { this._q = v; } }`, "qux"],
89
- ["class-field/arrow property", `class Foo {\n onClick = () => {\n return 1;\n }\n}\n`, "onClick"],
90
- ["object-literal arrow member", `const o = { onClick: () => { return 1; } };`, "onClick"],
91
- ["object-literal function member", `const o = { onClick: function() { return 1; } };`, "onClick"],
92
- ["standalone function declaration", `export function helper(x) { return x; }`, "helper"],
93
- ])("finds a %s as a real definition (no false flag)", async (_label, content, member) => {
94
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), "pom-resolve-shape-"));
95
- try {
96
- const file = path.join(dir, "shape.js");
97
- fs.writeFileSync(file, content);
98
- const binding = { kind: "instance", name: "shape", classFile: file };
99
- const result = await resolveMemberSource(binding, member, [file]);
100
- expect(result.found).toBe(true);
101
- }
102
- finally {
103
- fs.rmSync(dir, { recursive: true, force: true });
104
- }
105
- });
106
- });
107
- describe("resolveMemberSource -- af-style", () => {
108
- it("finds a component-chain member via the one-hop imported component file", async () => {
109
- const binding = { kind: "instance", name: "list", classFile: path.join(AF, "asset-list.page.ts") };
110
- const result = await resolveMemberSource(binding, "okBtn", AF_POM_FILES);
111
- expect(result.found).toBe(true);
112
- expect(result.searched).toEqual([path.join(AF, "asset-list.page.ts"), path.join(AF, "workflow-footer.page.ts")]);
113
- });
114
- });
@@ -1 +0,0 @@
1
- export {};