@testspectra/cli 1.0.70 → 1.1.0-rc.0

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 (365) hide show
  1. package/LICENSE.md +48 -0
  2. package/README.md +36 -270
  3. package/bin/spectra.js +1 -1
  4. package/bin/testspectra-runner +0 -0
  5. package/demo-app/assets/index-BGllUp7o.js +140 -0
  6. package/demo-app/assets/index-BhlW-eXG.css +1 -0
  7. package/demo-app/index.html +2 -2
  8. package/dist/.tsbuildinfo +1 -0
  9. package/dist/commands/__tests__/doctor.test.d.ts +1 -0
  10. package/dist/commands/__tests__/doctor.test.js +39 -0
  11. package/dist/commands/__tests__/init.test.d.ts +1 -0
  12. package/dist/commands/__tests__/init.test.js +148 -0
  13. package/dist/commands/__tests__/license.test.d.ts +1 -0
  14. package/dist/commands/__tests__/license.test.js +13 -0
  15. package/dist/commands/__tests__/refactor.test.d.ts +1 -0
  16. package/dist/commands/__tests__/refactor.test.js +64 -0
  17. package/dist/commands/__tests__/run-e2e.test.d.ts +1 -0
  18. package/dist/commands/__tests__/run-e2e.test.js +422 -0
  19. package/dist/commands/__tests__/run.test.d.ts +1 -0
  20. package/dist/commands/__tests__/run.test.js +277 -0
  21. package/dist/commands/__tests__/watch.test.d.ts +1 -0
  22. package/dist/commands/__tests__/watch.test.js +155 -0
  23. package/dist/commands/add.js +86 -85
  24. package/dist/commands/demo.js +21 -11
  25. package/dist/commands/devices.d.ts +14 -2
  26. package/dist/commands/devices.js +44 -34
  27. package/dist/commands/doctor.d.ts +3 -1
  28. package/dist/commands/doctor.js +43 -264
  29. package/dist/commands/init.d.ts +1 -1
  30. package/dist/commands/init.js +206 -196
  31. package/dist/commands/install.d.ts +4 -0
  32. package/dist/commands/install.js +59 -0
  33. package/dist/commands/license.d.ts +4 -0
  34. package/dist/commands/license.js +30 -0
  35. package/dist/commands/lint.d.ts +5 -0
  36. package/dist/commands/lint.js +55 -0
  37. package/dist/commands/refactor.d.ts +9 -0
  38. package/dist/commands/refactor.js +172 -0
  39. package/dist/commands/run.d.ts +23 -2
  40. package/dist/commands/run.js +321 -111
  41. package/dist/commands/skills.d.ts +9 -0
  42. package/dist/commands/skills.js +28 -0
  43. package/dist/commands/sync-types.d.ts +4 -0
  44. package/dist/commands/sync-types.js +14 -0
  45. package/dist/commands/update.js +39 -43
  46. package/dist/commands/watch.d.ts +6 -0
  47. package/dist/commands/watch.js +46 -43
  48. package/dist/config/loader.d.ts +1 -1
  49. package/dist/config/loader.js +40 -25
  50. package/dist/config/schema.d.ts +117 -54
  51. package/dist/config/schema.js +41 -35
  52. package/dist/generator/__tests__/tsconfig-isolation.test.d.ts +1 -0
  53. package/dist/generator/__tests__/tsconfig-isolation.test.js +278 -0
  54. package/dist/generator/__tests__/type-generator.test.d.ts +1 -0
  55. package/dist/generator/__tests__/type-generator.test.js +386 -0
  56. package/dist/generator/index.d.ts +2 -0
  57. package/dist/generator/index.js +2 -0
  58. package/dist/generator/tsconfig-generator.d.ts +27 -0
  59. package/dist/generator/tsconfig-generator.js +384 -0
  60. package/dist/generator/type-generator.d.ts +36 -0
  61. package/dist/generator/type-generator.js +644 -0
  62. package/dist/index.d.ts +9 -5
  63. package/dist/index.js +151 -51
  64. package/dist/lifecycle/__tests__/lifecycle-engine.test.d.ts +1 -0
  65. package/dist/lifecycle/__tests__/lifecycle-engine.test.js +290 -0
  66. package/dist/lifecycle/hook-discovery.d.ts +24 -0
  67. package/dist/lifecycle/hook-discovery.js +60 -0
  68. package/dist/lifecycle/hook-dispatcher.d.ts +34 -0
  69. package/dist/lifecycle/hook-dispatcher.js +190 -0
  70. package/dist/lifecycle/index.d.ts +3 -0
  71. package/dist/lifecycle/index.js +3 -0
  72. package/dist/lifecycle/parallel-grouping.d.ts +27 -0
  73. package/dist/lifecycle/parallel-grouping.js +151 -0
  74. package/dist/linter/__tests__/anonymous-export.test.d.ts +1 -0
  75. package/dist/linter/__tests__/anonymous-export.test.js +184 -0
  76. package/dist/linter/__tests__/shared-lib-boundary.test.d.ts +1 -0
  77. package/dist/linter/__tests__/shared-lib-boundary.test.js +270 -0
  78. package/dist/linter/__tests__/spec-schema.test.d.ts +1 -0
  79. package/dist/linter/__tests__/spec-schema.test.js +369 -0
  80. package/dist/linter/__tests__/step-parity.test.d.ts +1 -0
  81. package/dist/linter/__tests__/step-parity.test.js +372 -0
  82. package/dist/linter/discovery.d.ts +30 -0
  83. package/dist/linter/discovery.js +249 -0
  84. package/dist/linter/extractor.d.ts +66 -0
  85. package/dist/linter/extractor.js +235 -0
  86. package/dist/linter/index.d.ts +7 -0
  87. package/dist/linter/index.js +7 -0
  88. package/dist/linter/parser.d.ts +24 -0
  89. package/dist/linter/parser.js +219 -0
  90. package/dist/linter/schemas/spec.schema.d.ts +83 -0
  91. package/dist/linter/schemas/spec.schema.js +150 -0
  92. package/dist/linter/schemas/suite.schema.d.ts +59 -0
  93. package/dist/linter/schemas/suite.schema.js +83 -0
  94. package/dist/linter/spec-linter.d.ts +23 -0
  95. package/dist/linter/spec-linter.js +595 -0
  96. package/dist/linter/types.d.ts +28 -0
  97. package/dist/linter/types.js +1 -0
  98. package/dist/mobile/__tests__/android-device-e2e.test.d.ts +1 -0
  99. package/dist/mobile/__tests__/android-device-e2e.test.js +53 -0
  100. package/dist/mobile/__tests__/device-pool.test.d.ts +1 -0
  101. package/dist/mobile/__tests__/device-pool.test.js +97 -0
  102. package/dist/mobile/device-pool.d.ts +23 -0
  103. package/dist/mobile/device-pool.js +1 -0
  104. package/dist/mobile/index.d.ts +1 -0
  105. package/dist/mobile/index.js +1 -0
  106. package/dist/refactor/__tests__/refactor-engine.test.d.ts +1 -0
  107. package/dist/refactor/__tests__/refactor-engine.test.js +873 -0
  108. package/dist/refactor/index.d.ts +1 -0
  109. package/dist/refactor/index.js +1 -0
  110. package/dist/refactor/refactor-engine.d.ts +50 -0
  111. package/dist/refactor/refactor-engine.js +587 -0
  112. package/dist/reporter/__tests__/semantic-formatter.test.d.ts +1 -0
  113. package/dist/reporter/__tests__/semantic-formatter.test.js +73 -0
  114. package/dist/reporter/semantic-formatter.d.ts +6 -0
  115. package/dist/reporter/semantic-formatter.js +191 -0
  116. package/dist/reporter/summary-view.d.ts +12 -0
  117. package/dist/reporter/summary-view.js +19 -0
  118. package/dist/reporter/terminal-stream.d.ts +32 -0
  119. package/dist/reporter/terminal-stream.js +82 -0
  120. package/dist/reporter/types.d.ts +2 -0
  121. package/dist/reporter/types.js +1 -0
  122. package/dist/runner/bridge.d.ts +10 -5
  123. package/dist/runner/bridge.js +101 -45
  124. package/dist/runner/reporter.d.ts +32 -2
  125. package/dist/runner/reporter.js +423 -13
  126. package/dist/server/demo.js +43 -44
  127. package/dist/types/generator.d.ts +1 -17
  128. package/dist/types/generator.js +1 -443
  129. package/dist/utils/__tests__/api-server.test.d.ts +1 -0
  130. package/dist/utils/__tests__/api-server.test.js +62 -0
  131. package/dist/utils/__tests__/demo-server.test.d.ts +1 -0
  132. package/dist/utils/__tests__/demo-server.test.js +35 -0
  133. package/dist/utils/api-server.d.ts +19 -0
  134. package/dist/utils/api-server.js +134 -0
  135. package/dist/utils/demo-server.d.ts +5 -0
  136. package/dist/utils/demo-server.js +46 -36
  137. package/package.json +24 -13
  138. package/templates/default/CLAUDE.md +12 -5
  139. package/templates/default/fixtures/apiData.json +24 -0
  140. package/templates/default/package.json +12 -3
  141. package/templates/default/page-objects/MatchersPage/mobile.ts +53 -17
  142. package/templates/default/page-objects/MatchersPage/web.ts +17 -2
  143. package/templates/default/page-objects/NavigationPage/mobile.ts +11 -2
  144. package/templates/default/page-objects/NavigationPage/web.ts +1 -1
  145. package/templates/default/page-objects/PlaygroundPage/mobile.ts +28 -18
  146. package/templates/default/page-objects/PlaygroundPage/web.ts +4 -2
  147. package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/mobile.test.ts +53 -0
  148. package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/spec.md +19 -0
  149. package/templates/default/specs/ApiInterception/TC-0008-fetch-mocking/web.test.ts +31 -0
  150. package/templates/default/specs/ApiInterception/TC-0009-post-mocking/android.test.ts +3 -0
  151. package/templates/default/specs/ApiInterception/TC-0009-post-mocking/common.test.ts +3 -0
  152. package/templates/default/specs/ApiInterception/TC-0009-post-mocking/mobile.test.ts +27 -0
  153. package/templates/default/specs/ApiInterception/TC-0009-post-mocking/spec.md +19 -0
  154. package/templates/default/specs/ApiInterception/TC-0009-post-mocking/web.test.ts +26 -0
  155. package/templates/default/specs/ApiInterception/TC-0012-direct-and-late-response/common.test.ts +33 -0
  156. package/templates/default/specs/ApiInterception/TC-0012-direct-and-late-response/spec.md +22 -0
  157. package/templates/default/specs/ApiInterception/TC-0013-real-network-call-recorded/common.test.ts +27 -0
  158. package/templates/default/specs/ApiInterception/TC-0013-real-network-call-recorded/spec.md +20 -0
  159. package/templates/default/specs/ApiInterception/TC-0015-mock-server-sent-events/spec.md +24 -0
  160. package/templates/default/specs/ApiInterception/TC-0015-mock-server-sent-events/web.test.ts +26 -0
  161. package/templates/default/specs/ApiInterception/TC-0016-bypass-websocket-with-app-level-mock/spec.md +37 -0
  162. package/templates/default/specs/ApiInterception/TC-0016-bypass-websocket-with-app-level-mock/web.test.ts +21 -0
  163. package/templates/default/specs/ApiInterception/TC-0017-bypass-captcha-with-test-mode-flag/spec.md +29 -0
  164. package/templates/default/specs/ApiInterception/TC-0017-bypass-captcha-with-test-mode-flag/web.test.ts +16 -0
  165. package/templates/default/specs/ApiInterception/suite.md +10 -0
  166. package/templates/default/specs/ApiSeeding/TC-0014-seed-and-cleanup-via-hooks/common.test.ts +30 -0
  167. package/templates/default/specs/ApiSeeding/TC-0014-seed-and-cleanup-via-hooks/spec.md +23 -0
  168. package/templates/default/specs/ApiSeeding/hooks/after/common.hook.ts +16 -0
  169. package/templates/default/specs/ApiSeeding/hooks/before/common.hook.ts +28 -0
  170. package/templates/default/specs/ApiSeeding/suite.md +9 -0
  171. package/templates/default/specs/BrowserContext/TC-0007-title-and-navigation/mobile.test.ts +7 -1
  172. package/templates/default/specs/BrowserContext/TC-0007-title-and-navigation/spec.md +5 -0
  173. package/templates/default/specs/BrowserContext/TC-0007-title-and-navigation/web.test.ts +17 -3
  174. package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/common.test.ts +26 -0
  175. package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/spec.md +7 -0
  176. package/templates/default/specs/ContentMatchers/TC-0006-collections-and-empty/mobile.test.ts +9 -1
  177. package/templates/default/specs/ContentMatchers/TC-0006-collections-and-empty/spec.md +5 -0
  178. package/templates/default/specs/ContentMatchers/TC-0006-collections-and-empty/web.test.ts +9 -4
  179. package/templates/default/specs/DeepLink/TC-0018-navigate-via-deep-link/mobile.test.ts +28 -0
  180. package/templates/default/specs/DeepLink/TC-0018-navigate-via-deep-link/spec.md +29 -0
  181. package/templates/default/specs/DeepLink/suite.md +9 -0
  182. package/templates/default/specs/ElementMatchers/TC-0003-visibility-and-dom/mobile.test.ts +9 -1
  183. package/templates/default/specs/ElementMatchers/TC-0003-visibility-and-dom/spec.md +5 -0
  184. package/templates/default/specs/ElementMatchers/TC-0003-visibility-and-dom/web.test.ts +9 -3
  185. package/templates/default/specs/ElementMatchers/TC-0004-states-and-attributes/mobile.test.ts +27 -1
  186. package/templates/default/specs/ElementMatchers/TC-0004-states-and-attributes/spec.md +7 -0
  187. package/templates/default/specs/ElementMatchers/TC-0004-states-and-attributes/web.test.ts +27 -6
  188. package/templates/default/specs/ElementMatchers/suite.md +2 -1
  189. package/templates/default/specs/PermissionRationale/TC-0010-camera-permission-allow/mobile.test.ts +26 -0
  190. package/templates/default/specs/PermissionRationale/TC-0010-camera-permission-allow/spec.md +22 -0
  191. package/templates/default/specs/PermissionRationale/TC-0011-camera-permission-deny/mobile.test.ts +13 -0
  192. package/templates/default/specs/PermissionRationale/TC-0011-camera-permission-deny/spec.md +20 -0
  193. package/templates/default/specs/PermissionRationale/suite.md +9 -0
  194. package/templates/default/specs/Playground/TC-0001-form-controls/mobile.test.ts +4 -1
  195. package/templates/default/specs/Playground/TC-0001-form-controls/spec.md +6 -0
  196. package/templates/default/specs/Playground/TC-0001-form-controls/web.test.ts +4 -4
  197. package/templates/default/specs/Playground/TC-0002-toggle-elements/mobile.test.ts +4 -1
  198. package/templates/default/specs/Playground/TC-0002-toggle-elements/spec.md +6 -0
  199. package/templates/default/specs/Playground/TC-0002-toggle-elements/web.test.ts +3 -3
  200. package/templates/default/spectra.config.ts +21 -15
  201. package/templates/default/support/actions/fillCredentials/mobile.action.ts +3 -3
  202. package/templates/default/support/actions/fillCredentials/web.action.ts +1 -1
  203. package/templates/default/support/steps/togglePlaygroundStates/mobile.step.ts +3 -1
  204. package/templates/default/support/steps/togglePlaygroundStates/web.step.ts +3 -3
  205. package/templates/default/support/steps/verifyPlaygroundState/mobile.step.ts +4 -2
  206. package/templates/default/support/steps/verifyPlaygroundState/web.step.ts +4 -4
  207. package/templates/default/tsconfig.json +3 -1
  208. package/templates/nx/.nx/workspace-data/70094CFD-E89B-57A1-9619-2FC5F4963C54.db +0 -0
  209. package/templates/nx/.nx/workspace-data/70094CFD-E89B-57A1-9619-2FC5F4963C54.db-shm +0 -0
  210. package/templates/nx/.nx/workspace-data/70094CFD-E89B-57A1-9619-2FC5F4963C54.db-wal +0 -0
  211. package/templates/nx/.nx/workspace-data/d/daemon.log +4306 -0
  212. package/templates/nx/.nx/workspace-data/d/server-process.json +3 -0
  213. package/templates/nx/.nx/workspace-data/file-map.json +452 -0
  214. package/templates/nx/.nx/workspace-data/lockfile.hash +1 -0
  215. package/templates/nx/.nx/workspace-data/nx_files.nxt +0 -0
  216. package/templates/nx/.nx/workspace-data/parsed-lock-file.json +13485 -0
  217. package/templates/nx/.nx/workspace-data/project-graph.json +14389 -0
  218. package/templates/nx/CLAUDE.md +2 -2
  219. package/templates/nx/package.json +6 -4
  220. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0008-fetch-mocking/mobile.test.ts +27 -0
  221. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0008-fetch-mocking/spec.md +12 -0
  222. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0008-fetch-mocking/web.test.ts +27 -0
  223. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0009-post-mocking/mobile.test.ts +24 -0
  224. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0009-post-mocking/spec.md +12 -0
  225. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/TC-0009-post-mocking/web.test.ts +24 -0
  226. package/templates/nx/packages/matchers/e2e/specs/ApiInterception/suite.md +9 -0
  227. package/templates/nx/packages/matchers/e2e/specs/BrowserContext/TC-0007-title-and-navigation/mobile.test.ts +1 -1
  228. package/templates/nx/packages/matchers/e2e/specs/BrowserContext/TC-0007-title-and-navigation/web.test.ts +17 -3
  229. package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0005-text-and-values/mobile.test.ts +1 -1
  230. package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0005-text-and-values/web.test.ts +15 -5
  231. package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0006-collections-and-empty/mobile.test.ts +1 -1
  232. package/templates/nx/packages/matchers/e2e/specs/ContentMatchers/TC-0006-collections-and-empty/web.test.ts +9 -4
  233. package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0003-visibility-and-dom/mobile.test.ts +1 -1
  234. package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0003-visibility-and-dom/web.test.ts +9 -3
  235. package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0004-states-and-attributes/mobile.test.ts +1 -1
  236. package/templates/nx/packages/matchers/e2e/specs/ElementMatchers/TC-0004-states-and-attributes/web.test.ts +27 -6
  237. package/templates/nx/packages/playground/e2e/specs/Playground/TC-0001-form-controls/mobile.test.ts +1 -1
  238. package/templates/nx/packages/playground/e2e/specs/Playground/TC-0001-form-controls/web.test.ts +4 -4
  239. package/templates/nx/packages/playground/e2e/specs/Playground/TC-0002-toggle-elements/mobile.test.ts +1 -1
  240. package/templates/nx/packages/playground/e2e/specs/Playground/TC-0002-toggle-elements/web.test.ts +3 -3
  241. package/templates/nx/pnpm-lock.yaml +6663 -0
  242. package/templates/nx/pnpm-workspace.yaml +2 -1
  243. package/templates/nx/shared/testing/fixtures/apiData.json +24 -0
  244. package/templates/nx/shared/testing/page-objects/MatchersPage/mobile.ts +13 -1
  245. package/templates/nx/shared/testing/page-objects/MatchersPage/web.ts +85 -17
  246. package/templates/nx/shared/testing/page-objects/NavigationPage/mobile.ts +1 -1
  247. package/templates/nx/shared/testing/page-objects/NavigationPage/web.ts +1 -1
  248. package/templates/nx/shared/testing/page-objects/PlaygroundPage/mobile.ts +1 -1
  249. package/templates/nx/shared/testing/page-objects/PlaygroundPage/web.ts +4 -2
  250. package/templates/nx/shared/testing/project.json +19 -0
  251. package/templates/nx/shared/testing/support/actions/fillCredentials/mobile.action.ts +1 -1
  252. package/templates/nx/shared/testing/support/actions/fillCredentials/web.action.ts +1 -1
  253. package/templates/nx/shared/testing/support/steps/togglePlaygroundStates/mobile.step.ts +1 -1
  254. package/templates/nx/shared/testing/support/steps/togglePlaygroundStates/web.step.ts +3 -3
  255. package/templates/nx/shared/testing/support/steps/verifyPlaygroundState/mobile.step.ts +2 -2
  256. package/templates/nx/shared/testing/support/steps/verifyPlaygroundState/web.step.ts +4 -4
  257. package/templates/nx/spectra.config.ts +19 -13
  258. package/templates/nx/tsconfig.json +3 -1
  259. package/demo-app/assets/index-DAUlrHTr.css +0 -1
  260. package/demo-app/assets/index-DN2Kb0A8.js +0 -100
  261. package/dist/index.cjs +0 -101
  262. package/dist/plugin.cjs +0 -575
  263. package/dist/plugin.d.ts +0 -16
  264. package/dist/plugin.js +0 -184
  265. package/dist/step/index.d.ts +0 -6
  266. package/dist/step/index.js +0 -6
  267. package/dist/step/matchers.d.ts +0 -14
  268. package/dist/step/matchers.js +0 -114
  269. package/dist/step/proto.d.ts +0 -46
  270. package/dist/step/proto.js +0 -114
  271. package/dist/step/runner/collection.d.ts +0 -13
  272. package/dist/step/runner/collection.js +0 -51
  273. package/dist/step/runner/single.d.ts +0 -21
  274. package/dist/step/runner/single.js +0 -138
  275. package/dist/step/spectra.d.ts +0 -34
  276. package/dist/step/spectra.js +0 -156
  277. package/dist/step/types.d.ts +0 -32
  278. package/dist/step/types.js +0 -5
  279. package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/mobile.test.ts +0 -3
  280. package/templates/default/specs/ContentMatchers/TC-0005-text-and-values/web.test.ts +0 -7
  281. package/templates/default/tsconfig.spectra.android.json +0 -46
  282. package/templates/default/tsconfig.spectra.ios.json +0 -46
  283. package/templates/default/tsconfig.spectra.json +0 -22
  284. package/templates/default/tsconfig.spectra.web.json +0 -53
  285. package/templates/nx/fixtures/playgroundData.json +0 -7
  286. package/templates/nx/global-hooks/after/mobile.hook.ts +0 -3
  287. package/templates/nx/global-hooks/after/web.hook.ts +0 -3
  288. package/templates/nx/global-hooks/before/mobile.hook.ts +0 -3
  289. package/templates/nx/global-hooks/before/web.hook.ts +0 -3
  290. package/templates/nx/page-objects/MatchersPage/mobile.ts +0 -21
  291. package/templates/nx/page-objects/MatchersPage/web.ts +0 -23
  292. package/templates/nx/page-objects/NavigationPage/mobile.ts +0 -5
  293. package/templates/nx/page-objects/NavigationPage/web.ts +0 -8
  294. package/templates/nx/page-objects/PlaygroundPage/mobile.ts +0 -26
  295. package/templates/nx/page-objects/PlaygroundPage/web.ts +0 -29
  296. package/templates/nx/specs/BrowserContext/TC-0007-title-and-navigation/mobile.test.ts +0 -3
  297. package/templates/nx/specs/BrowserContext/TC-0007-title-and-navigation/spec.md +0 -12
  298. package/templates/nx/specs/BrowserContext/TC-0007-title-and-navigation/web.test.ts +0 -5
  299. package/templates/nx/specs/BrowserContext/suite.md +0 -9
  300. package/templates/nx/specs/ContentMatchers/TC-0005-text-and-values/mobile.test.ts +0 -3
  301. package/templates/nx/specs/ContentMatchers/TC-0005-text-and-values/spec.md +0 -12
  302. package/templates/nx/specs/ContentMatchers/TC-0005-text-and-values/web.test.ts +0 -7
  303. package/templates/nx/specs/ContentMatchers/TC-0006-collections-and-empty/mobile.test.ts +0 -3
  304. package/templates/nx/specs/ContentMatchers/TC-0006-collections-and-empty/spec.md +0 -12
  305. package/templates/nx/specs/ContentMatchers/TC-0006-collections-and-empty/web.test.ts +0 -6
  306. package/templates/nx/specs/ContentMatchers/suite.md +0 -9
  307. package/templates/nx/specs/ElementMatchers/TC-0003-visibility-and-dom/mobile.test.ts +0 -3
  308. package/templates/nx/specs/ElementMatchers/TC-0003-visibility-and-dom/spec.md +0 -12
  309. package/templates/nx/specs/ElementMatchers/TC-0003-visibility-and-dom/web.test.ts +0 -5
  310. package/templates/nx/specs/ElementMatchers/TC-0004-states-and-attributes/mobile.test.ts +0 -3
  311. package/templates/nx/specs/ElementMatchers/TC-0004-states-and-attributes/spec.md +0 -12
  312. package/templates/nx/specs/ElementMatchers/TC-0004-states-and-attributes/web.test.ts +0 -8
  313. package/templates/nx/specs/ElementMatchers/hooks/after/mobile.hook.ts +0 -1
  314. package/templates/nx/specs/ElementMatchers/hooks/after/web.hook.ts +0 -1
  315. package/templates/nx/specs/ElementMatchers/hooks/afterEach/mobile.hook.ts +0 -1
  316. package/templates/nx/specs/ElementMatchers/hooks/afterEach/web.hook.ts +0 -1
  317. package/templates/nx/specs/ElementMatchers/hooks/before/mobile.hook.ts +0 -1
  318. package/templates/nx/specs/ElementMatchers/hooks/before/web.hook.ts +0 -1
  319. package/templates/nx/specs/ElementMatchers/hooks/beforeEach/mobile.hook.ts +0 -1
  320. package/templates/nx/specs/ElementMatchers/hooks/beforeEach/web.hook.ts +0 -1
  321. package/templates/nx/specs/ElementMatchers/suite.md +0 -9
  322. package/templates/nx/specs/Playground/TC-0001-form-controls/mobile.test.ts +0 -3
  323. package/templates/nx/specs/Playground/TC-0001-form-controls/spec.md +0 -12
  324. package/templates/nx/specs/Playground/TC-0001-form-controls/web.test.ts +0 -6
  325. package/templates/nx/specs/Playground/TC-0002-toggle-elements/mobile.test.ts +0 -3
  326. package/templates/nx/specs/Playground/TC-0002-toggle-elements/spec.md +0 -12
  327. package/templates/nx/specs/Playground/TC-0002-toggle-elements/web.test.ts +0 -6
  328. package/templates/nx/specs/Playground/hooks/after/mobile.hook.ts +0 -1
  329. package/templates/nx/specs/Playground/hooks/after/web.hook.ts +0 -1
  330. package/templates/nx/specs/Playground/hooks/afterEach/mobile.hook.ts +0 -1
  331. package/templates/nx/specs/Playground/hooks/afterEach/web.hook.ts +0 -1
  332. package/templates/nx/specs/Playground/hooks/before/mobile.hook.ts +0 -1
  333. package/templates/nx/specs/Playground/hooks/before/web.hook.ts +0 -1
  334. package/templates/nx/specs/Playground/hooks/beforeEach/mobile.hook.ts +0 -1
  335. package/templates/nx/specs/Playground/hooks/beforeEach/web.hook.ts +0 -1
  336. package/templates/nx/specs/Playground/suite.md +0 -9
  337. package/templates/nx/support/actions/fillCredentials/mobile.action.ts +0 -4
  338. package/templates/nx/support/actions/fillCredentials/web.action.ts +0 -4
  339. package/templates/nx/support/steps/togglePlaygroundStates/mobile.step.ts +0 -3
  340. package/templates/nx/support/steps/togglePlaygroundStates/step.md +0 -7
  341. package/templates/nx/support/steps/togglePlaygroundStates/web.step.ts +0 -5
  342. package/templates/nx/support/steps/verifyPlaygroundState/mobile.step.ts +0 -4
  343. package/templates/nx/support/steps/verifyPlaygroundState/step.md +0 -7
  344. package/templates/nx/support/steps/verifyPlaygroundState/web.step.ts +0 -6
  345. package/templates/nx/tsconfig.spectra.android.json +0 -39
  346. package/templates/nx/tsconfig.spectra.ios.json +0 -39
  347. package/templates/nx/tsconfig.spectra.json +0 -25
  348. package/templates/nx/tsconfig.spectra.shared.json +0 -25
  349. package/templates/nx/tsconfig.spectra.web.json +0 -45
  350. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/after/mobile.hook.ts +0 -0
  351. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/after/web.hook.ts +0 -0
  352. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/afterEach/mobile.hook.ts +0 -0
  353. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/afterEach/web.hook.ts +0 -0
  354. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/before/mobile.hook.ts +0 -0
  355. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/before/web.hook.ts +0 -0
  356. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/beforeEach/mobile.hook.ts +0 -0
  357. /package/templates/{nx/specs/BrowserContext → default/specs/ApiInterception}/hooks/beforeEach/web.hook.ts +0 -0
  358. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/after/mobile.hook.ts +0 -0
  359. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/after/web.hook.ts +0 -0
  360. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/afterEach/mobile.hook.ts +0 -0
  361. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/afterEach/web.hook.ts +0 -0
  362. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/before/mobile.hook.ts +0 -0
  363. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/before/web.hook.ts +0 -0
  364. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/beforeEach/mobile.hook.ts +0 -0
  365. /package/templates/nx/{specs/ContentMatchers → packages/matchers/e2e/specs/ApiInterception}/hooks/beforeEach/web.hook.ts +0 -0
package/dist/plugin.cjs DELETED
@@ -1,575 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
- // src/plugin.ts
31
- var plugin_exports = {};
32
- __export(plugin_exports, {
33
- default: () => plugin_default,
34
- init: () => init
35
- });
36
- module.exports = __toCommonJS(plugin_exports);
37
- var import_fs2 = __toESM(require("fs"), 1);
38
- var import_path2 = __toESM(require("path"), 1);
39
-
40
- // src/types/generator.ts
41
- var import_fs = __toESM(require("fs"), 1);
42
- var import_path = __toESM(require("path"), 1);
43
- var PLATFORM_HIERARCHY = {
44
- web: ["web", "common"],
45
- ios: ["ios", "mobile", "common"],
46
- android: ["android", "mobile", "common"],
47
- mobile: ["mobile", "common"],
48
- common: ["common"]
49
- };
50
- var TypeGenerator = class {
51
- /**
52
- * Discovers all feature directories and shared library directories.
53
- * Returns a map of scope -> base directory (e.g. { "shared": ".../shared/testing", "auth": ".../packages/features/auth/e2e" })
54
- */
55
- static getEntityScopes(cwd) {
56
- const scopes = [];
57
- const sharedCandidates = [
58
- import_path.default.join(cwd, "shared", "testing"),
59
- import_path.default.join(cwd, "shared"),
60
- import_path.default.join(cwd, "testing")
61
- ];
62
- for (const cand of sharedCandidates) {
63
- if (import_fs.default.existsSync(cand) && (import_fs.default.existsSync(import_path.default.join(cand, "page-objects")) || import_fs.default.existsSync(import_path.default.join(cand, "steps")) || import_fs.default.existsSync(import_path.default.join(cand, "actions")))) {
64
- if (!scopes.some((s) => s.dir === cand)) {
65
- scopes.push({ name: "shared", dir: cand, isShared: true });
66
- }
67
- }
68
- }
69
- function scanForFeatures(dir, depth) {
70
- if (depth <= 0 || !import_fs.default.existsSync(dir)) return;
71
- const base = import_path.default.basename(dir);
72
- if (base === "node_modules" || base === "dist" || base === ".git" || base === ".testspectra") return;
73
- if (base === "e2e" || base === "tests" || base === "specs") {
74
- const featureDir = import_path.default.dirname(dir);
75
- const featureName = import_path.default.basename(featureDir);
76
- if (!scopes.some((s) => s.dir === dir)) {
77
- scopes.push({ name: featureName, dir, isShared: false });
78
- }
79
- return;
80
- }
81
- try {
82
- const entries = import_fs.default.readdirSync(dir, { withFileTypes: true });
83
- for (const entry of entries) {
84
- if (entry.isDirectory()) {
85
- scanForFeatures(import_path.default.join(dir, entry.name), depth - 1);
86
- }
87
- }
88
- } catch {
89
- }
90
- }
91
- scanForFeatures(cwd, 6);
92
- return scopes;
93
- }
94
- static getPageObjectsDirsForScope(scopeDir, sharedDir) {
95
- const dirs = [];
96
- function scanDir(dir, maxDepth) {
97
- if (maxDepth <= 0 || !import_fs.default.existsSync(dir)) return;
98
- const base = import_path.default.basename(dir);
99
- if (base === "node_modules" || base === "dist" || base === ".git" || base === ".testspectra") return;
100
- if (base === "page-objects" || base === "pageobjects") {
101
- if (!dirs.includes(dir)) dirs.push(dir);
102
- return;
103
- }
104
- try {
105
- const entries = import_fs.default.readdirSync(dir, { withFileTypes: true });
106
- for (const entry of entries) {
107
- if (entry.isDirectory()) {
108
- scanDir(import_path.default.join(dir, entry.name), maxDepth - 1);
109
- }
110
- }
111
- } catch {
112
- }
113
- }
114
- if (!sharedDir && (import_fs.default.existsSync(import_path.default.join(scopeDir, "pnpm-workspace.yaml")) || import_fs.default.existsSync(import_path.default.join(scopeDir, "nx.json")))) {
115
- scanDir(scopeDir, 6);
116
- } else {
117
- const candidates = [
118
- import_path.default.join(scopeDir, "page-objects"),
119
- import_path.default.join(scopeDir, "pageobjects")
120
- ];
121
- if (sharedDir) {
122
- candidates.push(import_path.default.join(sharedDir, "page-objects"));
123
- candidates.push(import_path.default.join(sharedDir, "pageobjects"));
124
- }
125
- for (const c of candidates) {
126
- if (import_fs.default.existsSync(c) && !dirs.includes(c)) dirs.push(c);
127
- }
128
- }
129
- return dirs;
130
- }
131
- static getEntityDirsForScope(entityType, scopeDir, sharedDir) {
132
- const dirs = [];
133
- function scanDir(dir, maxDepth) {
134
- if (maxDepth <= 0 || !import_fs.default.existsSync(dir)) return;
135
- const base = import_path.default.basename(dir);
136
- if (base === "node_modules" || base === "dist" || base === ".git" || base === ".testspectra") return;
137
- if (base === entityType) {
138
- if (!dirs.includes(dir)) dirs.push(dir);
139
- return;
140
- }
141
- try {
142
- const entries = import_fs.default.readdirSync(dir, { withFileTypes: true });
143
- for (const entry of entries) {
144
- if (entry.isDirectory()) {
145
- scanDir(import_path.default.join(dir, entry.name), maxDepth - 1);
146
- }
147
- }
148
- } catch {
149
- }
150
- }
151
- if (!sharedDir && (import_fs.default.existsSync(import_path.default.join(scopeDir, "pnpm-workspace.yaml")) || import_fs.default.existsSync(import_path.default.join(scopeDir, "nx.json")))) {
152
- scanDir(scopeDir, 6);
153
- } else {
154
- const candidates = [import_path.default.join(scopeDir, entityType)];
155
- if (sharedDir) {
156
- candidates.push(import_path.default.join(sharedDir, entityType));
157
- }
158
- for (const c of candidates) {
159
- if (import_fs.default.existsSync(c) && !dirs.includes(c)) dirs.push(c);
160
- }
161
- }
162
- return dirs;
163
- }
164
- static generateDeclarationsForScope(cwd, outputTypesDir, scopeDir, sharedDir) {
165
- const poDirs = this.getPageObjectsDirsForScope(scopeDir, sharedDir);
166
- const actionsDirs = this.getEntityDirsForScope("actions", scopeDir, sharedDir);
167
- const stepsDirs = this.getEntityDirsForScope("steps", scopeDir, sharedDir);
168
- const platforms = ["web", "android", "ios", "mobile", "common"];
169
- const results = {};
170
- for (const platform of platforms) {
171
- const hierarchy = PLATFORM_HIERARCHY[platform];
172
- let content = `// Auto-generated ambient declarations for TestSpectra [${platform.toUpperCase()}]
173
- `;
174
- content += `// Managed automatically by TestSpectra Language Service Plugin.
175
-
176
- `;
177
- content += `/// <reference types="@wdio/globals/types" />
178
- `;
179
- content += `/// <reference types="@wdio/mocha-framework" />
180
- `;
181
- content += `/// <reference types="@testspectra/matchers" />
182
- `;
183
- content += `/// <reference path="./fixtures.d.ts" />
184
-
185
- `;
186
- const declaredPOMs = /* @__PURE__ */ new Set();
187
- for (const poDir of poDirs) {
188
- if (!import_fs.default.existsSync(poDir)) continue;
189
- const poEntries = import_fs.default.readdirSync(poDir, { withFileTypes: true });
190
- for (const entry of poEntries) {
191
- if (entry.name.startsWith(".")) continue;
192
- if (entry.isDirectory()) {
193
- const className = entry.name;
194
- if (declaredPOMs.has(className)) continue;
195
- const classFolder = import_path.default.join(poDir, className);
196
- let matchedFile = null;
197
- for (const stem of hierarchy) {
198
- const candidates = [
199
- import_path.default.join(classFolder, `${stem}.ts`),
200
- import_path.default.join(classFolder, `${stem}.page.ts`),
201
- import_path.default.join(classFolder, `${stem}.po.ts`),
202
- import_path.default.join(classFolder, "index.ts"),
203
- import_path.default.join(classFolder, "common.ts")
204
- ];
205
- for (const cand of candidates) {
206
- if (import_fs.default.existsSync(cand)) {
207
- matchedFile = import_path.default.relative(outputTypesDir, cand).replace(/\\/g, "/").replace(/\.ts$/, ".js");
208
- if (!matchedFile.startsWith(".")) matchedFile = `./${matchedFile}`;
209
- break;
210
- }
211
- }
212
- if (matchedFile) break;
213
- }
214
- if (matchedFile) {
215
- content += `declare const ${className}: (typeof import('${matchedFile}') extends { default: infer T } ? T : typeof import('${matchedFile}'));
216
- `;
217
- declaredPOMs.add(className);
218
- }
219
- } else if (entry.isFile() && entry.name.endsWith(".ts")) {
220
- const parts = entry.name.split(".");
221
- const className = parts[0];
222
- if (declaredPOMs.has(className)) continue;
223
- let isMatch = false;
224
- if (parts.length === 2) {
225
- isMatch = true;
226
- } else if (parts.length > 2) {
227
- const stem = parts[1];
228
- isMatch = hierarchy.includes(stem);
229
- }
230
- if (isMatch) {
231
- let rel = import_path.default.relative(outputTypesDir, import_path.default.join(poDir, entry.name)).replace(/\\/g, "/").replace(/\.ts$/, ".js");
232
- if (!rel.startsWith(".")) rel = `./${rel}`;
233
- content += `declare const ${className}: (typeof import('${rel}') extends { default: infer T } ? T : typeof import('${rel}'));
234
- `;
235
- declaredPOMs.add(className);
236
- }
237
- }
238
- }
239
- }
240
- content += `interface TestSpectraCustomActions {
241
- `;
242
- const declaredActions = /* @__PURE__ */ new Set();
243
- for (const actionsDir of actionsDirs) {
244
- if (!import_fs.default.existsSync(actionsDir)) continue;
245
- const actionEntries = import_fs.default.readdirSync(actionsDir, { withFileTypes: true });
246
- for (const entry of actionEntries) {
247
- if (entry.name.startsWith(".")) continue;
248
- if (entry.isDirectory()) {
249
- const actionName = entry.name;
250
- if (declaredActions.has(actionName)) continue;
251
- const actionFolder = import_path.default.join(actionsDir, actionName);
252
- let matchedFile = null;
253
- for (const stem of hierarchy) {
254
- const cand1 = import_path.default.join(actionFolder, `${stem}.action.ts`);
255
- const cand2 = import_path.default.join(actionFolder, `${stem}.ts`);
256
- if (import_fs.default.existsSync(cand1)) {
257
- matchedFile = import_path.default.relative(outputTypesDir, cand1).replace(/\\/g, "/").replace(/\.ts$/, ".js");
258
- break;
259
- } else if (import_fs.default.existsSync(cand2)) {
260
- matchedFile = import_path.default.relative(outputTypesDir, cand2).replace(/\\/g, "/").replace(/\.ts$/, ".js");
261
- break;
262
- }
263
- }
264
- if (matchedFile) {
265
- if (!matchedFile.startsWith(".")) matchedFile = `./${matchedFile}`;
266
- content += ` ${actionName}: (typeof import('${matchedFile}') extends { default: infer T } ? T : typeof import('${matchedFile}'));
267
- `;
268
- declaredActions.add(actionName);
269
- }
270
- } else if (entry.isFile() && entry.name.endsWith(".ts")) {
271
- const parts = entry.name.split(".");
272
- const stem = parts.length > 2 ? parts[parts.length - 2] : parts[0];
273
- const actionName = parts[0];
274
- if (hierarchy.includes(stem) || hierarchy.includes(parts[1])) {
275
- if (declaredActions.has(actionName)) continue;
276
- let rel = import_path.default.relative(outputTypesDir, import_path.default.join(actionsDir, entry.name)).replace(/\\/g, "/").replace(/\.ts$/, ".js");
277
- if (!rel.startsWith(".")) rel = `./${rel}`;
278
- content += ` ${actionName}: (typeof import('${rel}') extends { default: infer T } ? T : typeof import('${rel}'));
279
- `;
280
- declaredActions.add(actionName);
281
- }
282
- }
283
- }
284
- }
285
- content += `}
286
- `;
287
- content += `type TestSpectraActions = import('@testspectra/matchers').SpectraStatic & TestSpectraCustomActions;
288
- `;
289
- content += `declare const Spectra: TestSpectraActions;
290
-
291
- `;
292
- content += `interface TestSpectraSteps {
293
- `;
294
- const declaredSteps = /* @__PURE__ */ new Set();
295
- for (const stepsDir of stepsDirs) {
296
- if (!import_fs.default.existsSync(stepsDir)) continue;
297
- const stepEntries = import_fs.default.readdirSync(stepsDir, { withFileTypes: true });
298
- for (const entry of stepEntries) {
299
- if (entry.name.startsWith(".")) continue;
300
- if (entry.isDirectory()) {
301
- const stepName = entry.name;
302
- if (declaredSteps.has(stepName)) continue;
303
- const stepFolder = import_path.default.join(stepsDir, stepName);
304
- let matchedFile = null;
305
- for (const stem of hierarchy) {
306
- const cand1 = import_path.default.join(stepFolder, `${stem}.step.ts`);
307
- const cand2 = import_path.default.join(stepFolder, `${stem}.ts`);
308
- if (import_fs.default.existsSync(cand1)) {
309
- matchedFile = import_path.default.relative(outputTypesDir, cand1).replace(/\\/g, "/").replace(/\.ts$/, ".js");
310
- break;
311
- } else if (import_fs.default.existsSync(cand2)) {
312
- matchedFile = import_path.default.relative(outputTypesDir, cand2).replace(/\\/g, "/").replace(/\.ts$/, ".js");
313
- break;
314
- }
315
- }
316
- if (matchedFile) {
317
- if (!matchedFile.startsWith(".")) matchedFile = `./${matchedFile}`;
318
- content += ` ${stepName}: (typeof import('${matchedFile}') extends { default: infer T } ? T : typeof import('${matchedFile}'));
319
- `;
320
- declaredSteps.add(stepName);
321
- }
322
- } else if (entry.isFile() && entry.name.endsWith(".ts")) {
323
- const parts = entry.name.split(".");
324
- const stem = parts.length > 2 ? parts[parts.length - 2] : parts[0];
325
- const stepName = parts[0];
326
- if (hierarchy.includes(stem) || hierarchy.includes(parts[1])) {
327
- if (declaredSteps.has(stepName)) continue;
328
- let rel = import_path.default.relative(outputTypesDir, import_path.default.join(stepsDir, entry.name)).replace(/\\/g, "/").replace(/\.ts$/, ".js");
329
- if (!rel.startsWith(".")) rel = `./${rel}`;
330
- content += ` ${stepName}: (typeof import('${rel}') extends { default: infer T } ? T : typeof import('${rel}'));
331
- `;
332
- declaredSteps.add(stepName);
333
- }
334
- }
335
- }
336
- }
337
- content += `}
338
- `;
339
- content += `declare const Step: TestSpectraSteps;
340
-
341
- `;
342
- results[platform] = content;
343
- }
344
- return results;
345
- }
346
- static generateFixturesDeclarationForScope(scopeDir, sharedDir) {
347
- const fixturesDirs = this.getEntityDirsForScope("fixtures", scopeDir, sharedDir);
348
- let content = `// Auto-generated ambient fixture declarations for TestSpectra
349
- `;
350
- content += `// Managed automatically by TestSpectra Language Service Plugin.
351
-
352
- `;
353
- content += `interface TestSpectraFixtures {
354
- `;
355
- const declaredFixtures = /* @__PURE__ */ new Set();
356
- function scanFixtureDir(dir) {
357
- if (!import_fs.default.existsSync(dir)) return;
358
- try {
359
- const entries = import_fs.default.readdirSync(dir, { withFileTypes: true });
360
- for (const entry of entries) {
361
- if (entry.name.startsWith(".")) continue;
362
- if (entry.isDirectory()) {
363
- scanFixtureDir(import_path.default.join(dir, entry.name));
364
- } else if (entry.isFile()) {
365
- const parsed = import_path.default.parse(entry.name);
366
- const varName = parsed.name.replace(/[^a-zA-Z0-9_$]/g, "_");
367
- if (declaredFixtures.has(varName)) continue;
368
- content += ` readonly ${varName}: string;
369
- `;
370
- declaredFixtures.add(varName);
371
- }
372
- }
373
- } catch {
374
- }
375
- }
376
- for (const fixturesDir of fixturesDirs) {
377
- scanFixtureDir(fixturesDir);
378
- }
379
- content += `}
380
- `;
381
- content += `declare const Fixture: TestSpectraFixtures;
382
- `;
383
- return content;
384
- }
385
- static writeDeclarationFiles(cwd) {
386
- const rootTypesDir = import_path.default.join(cwd, ".testspectra", "types");
387
- if (!import_fs.default.existsSync(rootTypesDir)) {
388
- import_fs.default.mkdirSync(rootTypesDir, { recursive: true });
389
- }
390
- const scopes = this.getEntityScopes(cwd);
391
- const sharedScope = scopes.find((s) => s.isShared);
392
- const rootFixtures = this.generateFixturesDeclarationForScope(cwd);
393
- import_fs.default.writeFileSync(import_path.default.join(rootTypesDir, "fixtures.d.ts"), rootFixtures, "utf-8");
394
- const rootDeclarations = this.generateDeclarationsForScope(cwd, rootTypesDir, cwd);
395
- for (const [platform, content] of Object.entries(rootDeclarations)) {
396
- import_fs.default.writeFileSync(import_path.default.join(rootTypesDir, `${platform}.d.ts`), content, "utf-8");
397
- }
398
- if (sharedScope) {
399
- const sharedTypesDir = import_path.default.join(rootTypesDir, "shared");
400
- if (!import_fs.default.existsSync(sharedTypesDir)) import_fs.default.mkdirSync(sharedTypesDir, { recursive: true });
401
- const sharedFixtures = this.generateFixturesDeclarationForScope(sharedScope.dir);
402
- import_fs.default.writeFileSync(import_path.default.join(sharedTypesDir, "fixtures.d.ts"), sharedFixtures, "utf-8");
403
- const sharedDeclarations = this.generateDeclarationsForScope(cwd, sharedTypesDir, sharedScope.dir);
404
- for (const [platform, content] of Object.entries(sharedDeclarations)) {
405
- import_fs.default.writeFileSync(import_path.default.join(sharedTypesDir, `${platform}.d.ts`), content, "utf-8");
406
- }
407
- }
408
- const featureScopes = scopes.filter((s) => !s.isShared);
409
- for (const feature of featureScopes) {
410
- const featureTypesDir = import_path.default.join(rootTypesDir, "features", feature.name);
411
- if (!import_fs.default.existsSync(featureTypesDir)) import_fs.default.mkdirSync(featureTypesDir, { recursive: true });
412
- const featureFixtures = this.generateFixturesDeclarationForScope(feature.dir, sharedScope?.dir);
413
- import_fs.default.writeFileSync(import_path.default.join(featureTypesDir, "fixtures.d.ts"), featureFixtures, "utf-8");
414
- const featureDeclarations = this.generateDeclarationsForScope(
415
- cwd,
416
- featureTypesDir,
417
- feature.dir,
418
- sharedScope?.dir
419
- );
420
- for (const [platform, content] of Object.entries(featureDeclarations)) {
421
- import_fs.default.writeFileSync(import_path.default.join(featureTypesDir, `${platform}.d.ts`), content, "utf-8");
422
- }
423
- }
424
- const universalPath = import_path.default.join(rootTypesDir, "index.d.ts");
425
- import_fs.default.writeFileSync(universalPath, `/// <reference path="./common.d.ts" />
426
- `, "utf-8");
427
- }
428
- };
429
-
430
- // src/plugin.ts
431
- function findWorkspaceRoot(startDir) {
432
- let cur = import_path2.default.resolve(startDir);
433
- while (cur !== import_path2.default.dirname(cur)) {
434
- if (import_fs2.default.existsSync(import_path2.default.join(cur, "spectra.config.ts")) || import_fs2.default.existsSync(import_path2.default.join(cur, ".testspectra")) || import_fs2.default.existsSync(import_path2.default.join(cur, "pnpm-workspace.yaml")) || import_fs2.default.existsSync(import_path2.default.join(cur, "nx.json"))) {
435
- return cur;
436
- }
437
- cur = import_path2.default.dirname(cur);
438
- }
439
- return startDir;
440
- }
441
- function appendLog(workspaceRoot, message) {
442
- try {
443
- const logDir = import_path2.default.join(workspaceRoot, ".testspectra", "logs");
444
- if (!import_fs2.default.existsSync(logDir)) import_fs2.default.mkdirSync(logDir, { recursive: true });
445
- const logFile = import_path2.default.join(logDir, "plugin.log");
446
- const timestamp = (/* @__PURE__ */ new Date()).toISOString();
447
- import_fs2.default.appendFileSync(logFile, `[${timestamp}] ${message}
448
- `, "utf-8");
449
- } catch {
450
- }
451
- }
452
- function init(modules) {
453
- const tsModule = modules.typescript;
454
- function create(info) {
455
- const project = info.project;
456
- const configPath = typeof project.getConfigFilePath === "function" ? project.getConfigFilePath() : "";
457
- const projectDir = configPath ? import_path2.default.dirname(configPath) : project.getCurrentDirectory();
458
- const workspaceRoot = findWorkspaceRoot(projectDir);
459
- const log = (msg) => {
460
- try {
461
- info.project.projectService.logger.info(`[TestSpectra TS Plugin] ${msg}`);
462
- } catch {
463
- }
464
- appendLog(workspaceRoot, msg);
465
- };
466
- log(`Plugin initialized on project: ${projectDir} (resolved root: ${workspaceRoot})`);
467
- try {
468
- TypeGenerator.writeDeclarationFiles(workspaceRoot);
469
- if (typeof project.markAsDirty === "function") {
470
- project.markAsDirty();
471
- }
472
- log(`Generated ambient declarations on startup`);
473
- } catch (err) {
474
- log(`Failed initial type generation: ${err?.message}`);
475
- }
476
- let debounceTimer = null;
477
- const triggerRegeneration = (reason, sync = false) => {
478
- const doRegen = () => {
479
- try {
480
- TypeGenerator.writeDeclarationFiles(workspaceRoot);
481
- if (typeof project.markAsDirty === "function") {
482
- project.markAsDirty();
483
- }
484
- log(`Regenerated ambient declarations (${reason})`);
485
- } catch (err) {
486
- log(`Error during regeneration: ${err?.message}`);
487
- }
488
- };
489
- if (sync) {
490
- doRegen();
491
- } else {
492
- if (debounceTimer) clearTimeout(debounceTimer);
493
- debounceTimer = setTimeout(doRegen, 80);
494
- }
495
- };
496
- try {
497
- if (import_fs2.default.existsSync(workspaceRoot)) {
498
- const watcher = import_fs2.default.watch(workspaceRoot, { recursive: true }, (eventType, filename) => {
499
- if (!filename) return;
500
- const fn = filename.toString();
501
- if (fn.includes(".testspectra") || fn.includes("node_modules") || fn.includes(".git") || fn.includes("dist") || fn.includes(".nx")) {
502
- return;
503
- }
504
- if (fn.includes("fixtures") || fn.includes("page-objects") || fn.includes("pageobjects") || fn.includes("actions") || fn.includes("steps") || fn.includes("hooks") || fn.includes("spectra.config")) {
505
- log(`Detected file change [${eventType}]: ${fn}`);
506
- triggerRegeneration(`fs.watch '${eventType}' on ${fn}`);
507
- }
508
- });
509
- watcher.on("error", () => {
510
- });
511
- log(`Attached recursive fs.watch on ${workspaceRoot}`);
512
- }
513
- } catch (err) {
514
- log(`Note: Recursive fs.watch not supported or failed: ${err?.message}`);
515
- }
516
- if (!info.languageService) {
517
- return /* @__PURE__ */ Object.create(null);
518
- }
519
- const proxy = /* @__PURE__ */ Object.create(null);
520
- for (const k of Object.keys(info.languageService)) {
521
- const x = info.languageService[k];
522
- proxy[k] = (...args) => x.apply(info.languageService, args);
523
- }
524
- const originalGetCompletions = info.languageService.getCompletionsAtPosition;
525
- proxy.getCompletionsAtPosition = (fileName, position, options, formattingSettings) => {
526
- const ext = import_path2.default.extname(fileName);
527
- if (ext === ".ts" || ext === ".tsx" || ext === ".js" || ext === ".mjs") {
528
- triggerRegeneration(`completions at ${import_path2.default.basename(fileName)}`, false);
529
- }
530
- return originalGetCompletions.apply(info.languageService, [
531
- fileName,
532
- position,
533
- options,
534
- formattingSettings
535
- ]);
536
- };
537
- const originalGetQuickInfo = info.languageService.getQuickInfoAtPosition;
538
- proxy.getQuickInfoAtPosition = (fileName, position) => {
539
- return originalGetQuickInfo.apply(info.languageService, [fileName, position]);
540
- };
541
- return proxy;
542
- }
543
- function getExternalFiles(project) {
544
- try {
545
- let collectDts2 = function(dir) {
546
- if (!import_fs2.default.existsSync(dir)) return;
547
- const entries = import_fs2.default.readdirSync(dir, { withFileTypes: true });
548
- for (const entry of entries) {
549
- const fullPath = import_path2.default.join(dir, entry.name);
550
- if (entry.isDirectory()) {
551
- collectDts2(fullPath);
552
- } else if (entry.isFile() && entry.name.endsWith(".d.ts")) {
553
- files.push(fullPath);
554
- }
555
- }
556
- };
557
- var collectDts = collectDts2;
558
- const workspaceRoot = findWorkspaceRoot(project.getCurrentDirectory());
559
- const typesDir = import_path2.default.join(workspaceRoot, ".testspectra", "types");
560
- const files = [];
561
- collectDts2(typesDir);
562
- return files;
563
- } catch {
564
- return [];
565
- }
566
- }
567
- return { create, getExternalFiles };
568
- }
569
- init.TypeGenerator = TypeGenerator;
570
- var plugin_default = init;
571
- // Annotate the CommonJS export names for ESM import in node:
572
- 0 && (module.exports = {
573
- init
574
- });
575
- module.exports = init; module.exports.default = init; module.exports.TypeGenerator = init.TypeGenerator;
package/dist/plugin.d.ts DELETED
@@ -1,16 +0,0 @@
1
- import type ts from "typescript";
2
- /**
3
- * TypeScript Language Service Plugin Factory for TestSpectra.
4
- * Runs silently inside TSServer (VS Code, Cursor, WebStorm, Neovim, etc.).
5
- *
6
- * It generates and refreshes `.testspectra/types/` ambient declarations
7
- * automatically in the background whenever the project is opened or files change.
8
- */
9
- declare function init(modules: {
10
- typescript: typeof ts;
11
- }): {
12
- create: (info: ts.server.PluginCreateInfo) => any;
13
- getExternalFiles: (project: ts.server.Project) => string[];
14
- };
15
- export default init;
16
- export { init };