@thinkwise/testwise 0.2.67 → 0.2.99

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 (434) hide show
  1. package/Testwise.ts +35 -0
  2. package/artifact-builder/ArtifactManager.ts +25 -2
  3. package/artifact-builder/ComponentClassModelBuilder.ts +148 -0
  4. package/artifact-builder/InterfaceGenerator.ts +31 -33
  5. package/artifact-builder/ModelDataBuilder.ts +18 -20
  6. package/artifact-builder/ModelDataRefiner.ts +23 -3
  7. package/artifact-builder/SchemaGenerator.ts +45 -35
  8. package/artifact-builder/ScreenInterfaceRefiner.ts +25 -10
  9. package/artifact-builder/SelectorBuilder.ts +30 -24
  10. package/artifact-builder/SubjectClassModelBuilder.ts +209 -0
  11. package/artifact-builder/SubjectComponentGenerator.ts +67 -246
  12. package/artifact-builder/SubjectGenerator.ts +117 -230
  13. package/artifact-builder/SubjectRegistration.ts +41 -32
  14. package/artifact-builder/TsFileModel.ts +94 -0
  15. package/artifact-builder/TsFileSerializer.ts +247 -0
  16. package/artifact-builder/helpers/DataRetriever.ts +64 -27
  17. package/artifact-builder/helpers/NamingHandler.ts +23 -78
  18. package/artifact-builder/helpers/PipelinePaths.ts +123 -0
  19. package/artifact-builder/helpers/Stopwatch.ts +10 -0
  20. package/artifact-builder/helpers/index.ts +1 -0
  21. package/artifact-builder/index.ts +4 -0
  22. package/components/BaseComponentObjects.ts +17 -0
  23. package/components/action-bar/ActionBar.ts +35 -47
  24. package/components/action-bar/ActionBarObjects.ts +2 -0
  25. package/components/action-bar/CustomActionBar.ts +6 -0
  26. package/components/cardlist/Cardlist.ts +6 -0
  27. package/components/chart/Chart.ts +6 -0
  28. package/components/combined-filter/CombinedFilter.ts +9 -0
  29. package/components/cube-view-bar/CubeViewBar.ts +6 -0
  30. package/components/export/ExportComponent.ts +12 -0
  31. package/components/filter/ExcelStyleFilterPopup.ts +35 -2
  32. package/components/filter/FilterForm.ts +10 -0
  33. package/components/filter/FilterPopup.ts +30 -9
  34. package/components/filter/FilterPopupObjects.ts +10 -3
  35. package/components/filter/FindForm.ts +7 -0
  36. package/components/filter/ManagePrefilterPopup.ts +11 -0
  37. package/components/form/Form.ts +16 -0
  38. package/components/grid/Grid.ts +18 -1
  39. package/components/maps/Maps.ts +6 -0
  40. package/components/menu/ListBarMenuComponent.ts +10 -0
  41. package/components/pivot-grid/PivotGrid.ts +6 -0
  42. package/components/pivot-grid/PivotGridFieldList.ts +7 -0
  43. package/components/pop-up/AllRowsPopUp.ts +12 -0
  44. package/components/pop-up/PopUpComponent.ts +11 -0
  45. package/components/prefilter-list/PrefilterList.ts +9 -0
  46. package/components/preview/Preview.ts +6 -0
  47. package/components/report-bar/ReportBar.ts +6 -0
  48. package/components/report-tiles/ReportTiles.ts +6 -0
  49. package/components/scheduler/Scheduler.ts +6 -0
  50. package/components/snackbar/SnackBar.ts +12 -0
  51. package/components/splitter/Splitter.ts +6 -0
  52. package/components/tab/BaseTab.ts +5 -0
  53. package/components/tab/DetailTabPage.ts +11 -0
  54. package/components/tab/Tab.ts +10 -0
  55. package/components/task/TaskBar.ts +13 -3
  56. package/components/task/TaskTiles.ts +12 -3
  57. package/components/topbar/TopBar.ts +10 -0
  58. package/components/tree-view/TreeView.ts +9 -0
  59. package/controls/DateControl.ts +40 -1
  60. package/controls/FormComboBox.ts +30 -0
  61. package/controls/GridColumnControl.ts +34 -3
  62. package/controls/InputFieldControl.ts +49 -0
  63. package/controls/LookupDropdown.ts +29 -0
  64. package/dist/Testwise.js +35 -0
  65. package/dist/Testwise.js.map +1 -1
  66. package/dist/artifact-builder/ArtifactManager.d.ts +18 -1
  67. package/dist/artifact-builder/ArtifactManager.js +24 -2
  68. package/dist/artifact-builder/ArtifactManager.js.map +1 -1
  69. package/dist/artifact-builder/ComponentClassModelBuilder.d.ts +22 -0
  70. package/dist/artifact-builder/ComponentClassModelBuilder.js +115 -0
  71. package/dist/artifact-builder/ComponentClassModelBuilder.js.map +1 -0
  72. package/dist/artifact-builder/InterfaceGenerator.d.ts +15 -6
  73. package/dist/artifact-builder/InterfaceGenerator.js +27 -26
  74. package/dist/artifact-builder/InterfaceGenerator.js.map +1 -1
  75. package/dist/artifact-builder/ModelDataBuilder.d.ts +7 -0
  76. package/dist/artifact-builder/ModelDataBuilder.js +13 -5
  77. package/dist/artifact-builder/ModelDataBuilder.js.map +1 -1
  78. package/dist/artifact-builder/ModelDataRefiner.d.ts +18 -1
  79. package/dist/artifact-builder/ModelDataRefiner.js +18 -3
  80. package/dist/artifact-builder/ModelDataRefiner.js.map +1 -1
  81. package/dist/artifact-builder/SchemaGenerator.d.ts +21 -5
  82. package/dist/artifact-builder/SchemaGenerator.js +38 -26
  83. package/dist/artifact-builder/SchemaGenerator.js.map +1 -1
  84. package/dist/artifact-builder/ScreenInterfaceRefiner.d.ts +18 -1
  85. package/dist/artifact-builder/ScreenInterfaceRefiner.js +23 -9
  86. package/dist/artifact-builder/ScreenInterfaceRefiner.js.map +1 -1
  87. package/dist/artifact-builder/SelectorBuilder.d.ts +18 -5
  88. package/dist/artifact-builder/SelectorBuilder.js +29 -14
  89. package/dist/artifact-builder/SelectorBuilder.js.map +1 -1
  90. package/dist/artifact-builder/SubjectClassModelBuilder.d.ts +38 -0
  91. package/dist/artifact-builder/SubjectClassModelBuilder.js +158 -0
  92. package/dist/artifact-builder/SubjectClassModelBuilder.js.map +1 -0
  93. package/dist/artifact-builder/SubjectComponentGenerator.d.ts +25 -14
  94. package/dist/artifact-builder/SubjectComponentGenerator.js +65 -189
  95. package/dist/artifact-builder/SubjectComponentGenerator.js.map +1 -1
  96. package/dist/artifact-builder/SubjectGenerator.d.ts +32 -13
  97. package/dist/artifact-builder/SubjectGenerator.js +81 -165
  98. package/dist/artifact-builder/SubjectGenerator.js.map +1 -1
  99. package/dist/artifact-builder/SubjectRegistration.d.ts +22 -8
  100. package/dist/artifact-builder/SubjectRegistration.js +29 -14
  101. package/dist/artifact-builder/SubjectRegistration.js.map +1 -1
  102. package/dist/artifact-builder/TsFileModel.d.ts +86 -0
  103. package/dist/artifact-builder/TsFileModel.js +2 -0
  104. package/dist/artifact-builder/TsFileModel.js.map +1 -0
  105. package/dist/artifact-builder/TsFileSerializer.d.ts +19 -0
  106. package/dist/artifact-builder/TsFileSerializer.js +225 -0
  107. package/dist/artifact-builder/TsFileSerializer.js.map +1 -0
  108. package/dist/artifact-builder/helpers/DataRetriever.d.ts +22 -3
  109. package/dist/artifact-builder/helpers/DataRetriever.js +56 -26
  110. package/dist/artifact-builder/helpers/DataRetriever.js.map +1 -1
  111. package/dist/artifact-builder/helpers/NamingHandler.d.ts +18 -6
  112. package/dist/artifact-builder/helpers/NamingHandler.js +20 -61
  113. package/dist/artifact-builder/helpers/NamingHandler.js.map +1 -1
  114. package/dist/artifact-builder/helpers/PipelinePaths.d.ts +52 -0
  115. package/dist/artifact-builder/helpers/PipelinePaths.js +99 -0
  116. package/dist/artifact-builder/helpers/PipelinePaths.js.map +1 -0
  117. package/dist/artifact-builder/helpers/Stopwatch.d.ts +10 -0
  118. package/dist/artifact-builder/helpers/Stopwatch.js +10 -0
  119. package/dist/artifact-builder/helpers/Stopwatch.js.map +1 -1
  120. package/dist/artifact-builder/helpers/index.d.ts +1 -0
  121. package/dist/artifact-builder/helpers/index.js +1 -0
  122. package/dist/artifact-builder/helpers/index.js.map +1 -1
  123. package/dist/artifact-builder/index.d.ts +4 -0
  124. package/dist/artifact-builder/index.js +4 -0
  125. package/dist/artifact-builder/index.js.map +1 -1
  126. package/dist/components/BaseComponentObjects.d.ts +17 -0
  127. package/dist/components/BaseComponentObjects.js +17 -0
  128. package/dist/components/BaseComponentObjects.js.map +1 -1
  129. package/dist/components/action-bar/ActionBar.d.ts +21 -24
  130. package/dist/components/action-bar/ActionBar.js +31 -24
  131. package/dist/components/action-bar/ActionBar.js.map +1 -1
  132. package/dist/components/action-bar/ActionBarObjects.d.ts +1 -0
  133. package/dist/components/action-bar/ActionBarObjects.js +1 -0
  134. package/dist/components/action-bar/ActionBarObjects.js.map +1 -1
  135. package/dist/components/action-bar/CustomActionBar.d.ts +6 -0
  136. package/dist/components/action-bar/CustomActionBar.js +6 -0
  137. package/dist/components/action-bar/CustomActionBar.js.map +1 -1
  138. package/dist/components/cardlist/Cardlist.d.ts +6 -0
  139. package/dist/components/cardlist/Cardlist.js +6 -0
  140. package/dist/components/cardlist/Cardlist.js.map +1 -1
  141. package/dist/components/chart/Chart.d.ts +6 -0
  142. package/dist/components/chart/Chart.js +6 -0
  143. package/dist/components/chart/Chart.js.map +1 -1
  144. package/dist/components/combined-filter/CombinedFilter.d.ts +9 -0
  145. package/dist/components/combined-filter/CombinedFilter.js +9 -0
  146. package/dist/components/combined-filter/CombinedFilter.js.map +1 -1
  147. package/dist/components/cube-view-bar/CubeViewBar.d.ts +6 -0
  148. package/dist/components/cube-view-bar/CubeViewBar.js +6 -0
  149. package/dist/components/cube-view-bar/CubeViewBar.js.map +1 -1
  150. package/dist/components/export/ExportComponent.d.ts +12 -0
  151. package/dist/components/export/ExportComponent.js +12 -0
  152. package/dist/components/export/ExportComponent.js.map +1 -1
  153. package/dist/components/filter/ExcelStyleFilterPopup.d.ts +17 -4
  154. package/dist/components/filter/ExcelStyleFilterPopup.js +35 -23
  155. package/dist/components/filter/ExcelStyleFilterPopup.js.map +1 -1
  156. package/dist/components/filter/ExcelStyleFilterPopupObjects.d.ts +1 -1
  157. package/dist/components/filter/ExcelStyleFilterPopupObjects.js +2 -2
  158. package/dist/components/filter/ExcelStyleFilterPopupObjects.js.map +1 -1
  159. package/dist/components/filter/FilterForm.d.ts +10 -0
  160. package/dist/components/filter/FilterForm.js +10 -0
  161. package/dist/components/filter/FilterForm.js.map +1 -1
  162. package/dist/components/filter/FilterPopup.d.ts +22 -4
  163. package/dist/components/filter/FilterPopup.js +17 -9
  164. package/dist/components/filter/FilterPopup.js.map +1 -1
  165. package/dist/components/filter/FilterPopupObjects.d.ts +5 -2
  166. package/dist/components/filter/FilterPopupObjects.js +5 -2
  167. package/dist/components/filter/FilterPopupObjects.js.map +1 -1
  168. package/dist/components/filter/FindForm.d.ts +7 -0
  169. package/dist/components/filter/FindForm.js +7 -0
  170. package/dist/components/filter/FindForm.js.map +1 -1
  171. package/dist/components/filter/ManagePrefilterPopup.d.ts +11 -0
  172. package/dist/components/filter/ManagePrefilterPopup.js +11 -0
  173. package/dist/components/filter/ManagePrefilterPopup.js.map +1 -1
  174. package/dist/components/form/Form.d.ts +16 -0
  175. package/dist/components/form/Form.js +16 -0
  176. package/dist/components/form/Form.js.map +1 -1
  177. package/dist/components/grid/Grid.d.ts +17 -0
  178. package/dist/components/grid/Grid.js +18 -1
  179. package/dist/components/grid/Grid.js.map +1 -1
  180. package/dist/components/maps/Maps.d.ts +6 -0
  181. package/dist/components/maps/Maps.js +6 -0
  182. package/dist/components/maps/Maps.js.map +1 -1
  183. package/dist/components/menu/ListBarMenuComponent.d.ts +10 -0
  184. package/dist/components/menu/ListBarMenuComponent.js +10 -0
  185. package/dist/components/menu/ListBarMenuComponent.js.map +1 -1
  186. package/dist/components/pivot-grid/PivotGrid.d.ts +6 -0
  187. package/dist/components/pivot-grid/PivotGrid.js +6 -0
  188. package/dist/components/pivot-grid/PivotGrid.js.map +1 -1
  189. package/dist/components/pivot-grid/PivotGridFieldList.d.ts +7 -0
  190. package/dist/components/pivot-grid/PivotGridFieldList.js +7 -0
  191. package/dist/components/pivot-grid/PivotGridFieldList.js.map +1 -1
  192. package/dist/components/pop-up/AllRowsPopUp.d.ts +12 -0
  193. package/dist/components/pop-up/AllRowsPopUp.js +12 -0
  194. package/dist/components/pop-up/AllRowsPopUp.js.map +1 -1
  195. package/dist/components/pop-up/PopUpComponent.d.ts +11 -0
  196. package/dist/components/pop-up/PopUpComponent.js +11 -0
  197. package/dist/components/pop-up/PopUpComponent.js.map +1 -1
  198. package/dist/components/prefilter-list/PrefilterList.d.ts +9 -0
  199. package/dist/components/prefilter-list/PrefilterList.js +9 -0
  200. package/dist/components/prefilter-list/PrefilterList.js.map +1 -1
  201. package/dist/components/preview/Preview.d.ts +6 -0
  202. package/dist/components/preview/Preview.js +6 -0
  203. package/dist/components/preview/Preview.js.map +1 -1
  204. package/dist/components/report-bar/ReportBar.d.ts +6 -0
  205. package/dist/components/report-bar/ReportBar.js +6 -0
  206. package/dist/components/report-bar/ReportBar.js.map +1 -1
  207. package/dist/components/report-tiles/ReportTiles.d.ts +6 -0
  208. package/dist/components/report-tiles/ReportTiles.js +6 -0
  209. package/dist/components/report-tiles/ReportTiles.js.map +1 -1
  210. package/dist/components/scheduler/Scheduler.d.ts +6 -0
  211. package/dist/components/scheduler/Scheduler.js +6 -0
  212. package/dist/components/scheduler/Scheduler.js.map +1 -1
  213. package/dist/components/snackbar/SnackBar.d.ts +12 -0
  214. package/dist/components/snackbar/SnackBar.js +12 -0
  215. package/dist/components/snackbar/SnackBar.js.map +1 -1
  216. package/dist/components/splitter/Splitter.d.ts +6 -0
  217. package/dist/components/splitter/Splitter.js +6 -0
  218. package/dist/components/splitter/Splitter.js.map +1 -1
  219. package/dist/components/tab/BaseTab.d.ts +5 -0
  220. package/dist/components/tab/BaseTab.js +5 -0
  221. package/dist/components/tab/BaseTab.js.map +1 -1
  222. package/dist/components/tab/DetailTabPage.d.ts +11 -0
  223. package/dist/components/tab/DetailTabPage.js +11 -0
  224. package/dist/components/tab/DetailTabPage.js.map +1 -1
  225. package/dist/components/tab/Tab.d.ts +10 -0
  226. package/dist/components/tab/Tab.js +10 -0
  227. package/dist/components/tab/Tab.js.map +1 -1
  228. package/dist/components/task/TaskBar.d.ts +12 -2
  229. package/dist/components/task/TaskBar.js +13 -3
  230. package/dist/components/task/TaskBar.js.map +1 -1
  231. package/dist/components/task/TaskTiles.d.ts +11 -2
  232. package/dist/components/task/TaskTiles.js +12 -3
  233. package/dist/components/task/TaskTiles.js.map +1 -1
  234. package/dist/components/topbar/TopBar.d.ts +10 -0
  235. package/dist/components/topbar/TopBar.js +10 -0
  236. package/dist/components/topbar/TopBar.js.map +1 -1
  237. package/dist/components/tree-view/TreeView.d.ts +9 -0
  238. package/dist/components/tree-view/TreeView.js +9 -0
  239. package/dist/components/tree-view/TreeView.js.map +1 -1
  240. package/dist/controls/DateControl.d.ts +39 -0
  241. package/dist/controls/DateControl.js +18 -1
  242. package/dist/controls/DateControl.js.map +1 -1
  243. package/dist/controls/FormComboBox.d.ts +30 -0
  244. package/dist/controls/FormComboBox.js +8 -0
  245. package/dist/controls/FormComboBox.js.map +1 -1
  246. package/dist/controls/GridColumnControl.d.ts +30 -0
  247. package/dist/controls/GridColumnControl.js +12 -3
  248. package/dist/controls/GridColumnControl.js.map +1 -1
  249. package/dist/controls/InputFieldControl.d.ts +49 -0
  250. package/dist/controls/InputFieldControl.js +30 -0
  251. package/dist/controls/InputFieldControl.js.map +1 -1
  252. package/dist/controls/LookupDropdown.d.ts +29 -0
  253. package/dist/controls/LookupDropdown.js +8 -0
  254. package/dist/controls/LookupDropdown.js.map +1 -1
  255. package/dist/enums/ElementTypes.d.ts +18 -0
  256. package/dist/enums/ElementTypes.js +18 -0
  257. package/dist/enums/ElementTypes.js.map +1 -1
  258. package/dist/enums/ExportFormat.d.ts +8 -0
  259. package/dist/enums/ExportFormat.js +8 -0
  260. package/dist/enums/ExportFormat.js.map +1 -1
  261. package/dist/enums/LogLevel.d.ts +17 -0
  262. package/dist/enums/LogLevel.js +17 -1
  263. package/dist/enums/LogLevel.js.map +1 -1
  264. package/dist/enums/index.d.ts +1 -0
  265. package/dist/enums/index.js +1 -0
  266. package/dist/enums/index.js.map +1 -1
  267. package/dist/helpers/ConfigChecker.d.ts +13 -0
  268. package/dist/helpers/ConfigChecker.js +13 -0
  269. package/dist/helpers/ConfigChecker.js.map +1 -1
  270. package/dist/helpers/Ensure.d.ts +13 -0
  271. package/dist/helpers/Ensure.js +13 -0
  272. package/dist/helpers/Ensure.js.map +1 -1
  273. package/dist/helpers/FlightTracker.d.ts +13 -3
  274. package/dist/helpers/FlightTracker.js +103 -17
  275. package/dist/helpers/FlightTracker.js.map +1 -1
  276. package/dist/helpers/GlobalWaitEventHandler.d.ts +13 -0
  277. package/dist/helpers/GlobalWaitEventHandler.js +13 -0
  278. package/dist/helpers/GlobalWaitEventHandler.js.map +1 -1
  279. package/dist/helpers/LoginHelper.d.ts +35 -1
  280. package/dist/helpers/LoginHelper.js +46 -11
  281. package/dist/helpers/LoginHelper.js.map +1 -1
  282. package/dist/helpers/PathResolver.d.ts +22 -0
  283. package/dist/helpers/PathResolver.js +22 -0
  284. package/dist/helpers/PathResolver.js.map +1 -1
  285. package/dist/helpers/Poll.d.ts +13 -1
  286. package/dist/helpers/Poll.js +12 -0
  287. package/dist/helpers/Poll.js.map +1 -1
  288. package/dist/helpers/RegexHelper.d.ts +15 -0
  289. package/dist/helpers/RegexHelper.js +15 -3
  290. package/dist/helpers/RegexHelper.js.map +1 -1
  291. package/dist/helpers/SubjectNavigator.d.ts +26 -0
  292. package/dist/helpers/SubjectNavigator.js +51 -0
  293. package/dist/helpers/SubjectNavigator.js.map +1 -0
  294. package/dist/helpers/UserSimulationHelper.d.ts +14 -0
  295. package/dist/helpers/UserSimulationHelper.js +14 -0
  296. package/dist/helpers/UserSimulationHelper.js.map +1 -1
  297. package/dist/helpers/index.d.ts +1 -0
  298. package/dist/helpers/index.js +1 -0
  299. package/dist/helpers/index.js.map +1 -1
  300. package/dist/index.d.ts +6 -20
  301. package/dist/index.js +1 -0
  302. package/dist/index.js.map +1 -1
  303. package/dist/interfaces/IComponentObjects.d.ts +12 -0
  304. package/dist/interfaces/IComponentSchemaMeta.d.ts +15 -0
  305. package/dist/interfaces/IComponentSchemaMeta.js +2 -0
  306. package/dist/interfaces/IComponentSchemaMeta.js.map +1 -0
  307. package/dist/interfaces/IProperty.d.ts +13 -0
  308. package/dist/interfaces/IRegisteredSubjects.d.ts +12 -0
  309. package/dist/interfaces/ISeedSubjectDraft.d.ts +16 -0
  310. package/dist/interfaces/ISeedSubjectDraft.js +2 -0
  311. package/dist/interfaces/ISeedSubjectDraft.js.map +1 -0
  312. package/dist/interfaces/ISubject.d.ts +13 -0
  313. package/dist/interfaces/ISubjectDetail.d.ts +11 -0
  314. package/dist/interfaces/ISubjectDetail.js +2 -0
  315. package/dist/interfaces/ISubjectDetail.js.map +1 -0
  316. package/dist/mcp/ArtifactResolver.d.ts +152 -0
  317. package/dist/mcp/ArtifactResolver.js +232 -0
  318. package/dist/mcp/ArtifactResolver.js.map +1 -0
  319. package/dist/mcp/index.d.ts +2 -0
  320. package/dist/mcp/index.js +2 -0
  321. package/dist/mcp/index.js.map +1 -0
  322. package/dist/page-extensions/GlobalComponents.d.ts +30 -0
  323. package/dist/page-extensions/GlobalComponents.js +30 -0
  324. package/dist/page-extensions/GlobalComponents.js.map +1 -1
  325. package/dist/page-extensions/GoToDeepLink.d.ts +9 -0
  326. package/dist/page-extensions/GoToDeepLink.js +9 -0
  327. package/dist/page-extensions/GoToDeepLink.js.map +1 -1
  328. package/dist/page-extensions/LoginFeatures.d.ts +8 -0
  329. package/dist/page-extensions/LoginFeatures.js +8 -0
  330. package/dist/page-extensions/LoginFeatures.js.map +1 -1
  331. package/dist/page-extensions/SubjectRegistry.d.ts +31 -0
  332. package/dist/page-extensions/SubjectRegistry.js +31 -0
  333. package/dist/page-extensions/SubjectRegistry.js.map +1 -1
  334. package/dist/page-extensions/UserSimulation.d.ts +21 -0
  335. package/dist/page-extensions/UserSimulation.js +21 -0
  336. package/dist/page-extensions/UserSimulation.js.map +1 -1
  337. package/dist/page-extensions/WaitEventHandler.d.ts +20 -0
  338. package/dist/page-extensions/WaitEventHandler.js +20 -0
  339. package/dist/page-extensions/WaitEventHandler.js.map +1 -1
  340. package/dist/page-overrides/ClickOverride.d.ts +23 -2
  341. package/dist/page-overrides/ClickOverride.js +34 -50
  342. package/dist/page-overrides/ClickOverride.js.map +1 -1
  343. package/dist/page-overrides/FillOverride.d.ts +23 -0
  344. package/dist/page-overrides/FillOverride.js +46 -66
  345. package/dist/page-overrides/FillOverride.js.map +1 -1
  346. package/dist/services/ConfigBuilder.d.ts +24 -0
  347. package/dist/services/ConfigBuilder.js +24 -0
  348. package/dist/services/ConfigBuilder.js.map +1 -1
  349. package/dist/services/IndiciumApi.service.d.ts +26 -0
  350. package/dist/services/IndiciumApi.service.js +40 -5
  351. package/dist/services/IndiciumApi.service.js.map +1 -1
  352. package/dist/services/Logger.d.ts +13 -0
  353. package/dist/services/Logger.js +39 -0
  354. package/dist/services/Logger.js.map +1 -1
  355. package/dist/types/Components.d.ts +18 -1
  356. package/dist/types/Components.js +0 -1
  357. package/dist/types/Components.js.map +1 -1
  358. package/dist/types/LocatorType.d.ts +5 -0
  359. package/dist/types/LocatorType.js +2 -0
  360. package/dist/types/LocatorType.js.map +1 -0
  361. package/dist/types/PollTypes.d.ts +8 -0
  362. package/dist/types/Test.d.ts +18 -0
  363. package/dist/types/Universal.d.ts +12 -0
  364. package/dist/types/index.d.ts +2 -0
  365. package/dist/types/index.js +2 -0
  366. package/dist/types/index.js.map +1 -1
  367. package/enums/ElementTypes.ts +18 -0
  368. package/enums/ExportFormat.ts +8 -0
  369. package/enums/LogLevel.ts +17 -1
  370. package/enums/index.ts +1 -0
  371. package/helpers/ConfigChecker.ts +13 -0
  372. package/helpers/Ensure.ts +13 -0
  373. package/helpers/FlightTracker.ts +109 -20
  374. package/helpers/GlobalWaitEventHandler.ts +13 -0
  375. package/helpers/LoginHelper.ts +49 -12
  376. package/helpers/PathResolver.ts +22 -0
  377. package/helpers/Poll.ts +13 -1
  378. package/helpers/RegexHelper.ts +15 -3
  379. package/helpers/SubjectNavigator.ts +57 -0
  380. package/helpers/UserSimulationHelper.ts +14 -0
  381. package/helpers/index.ts +1 -0
  382. package/index.ts +1 -0
  383. package/interfaces/IComponentObjects.ts +12 -0
  384. package/interfaces/IComponentSchemaMeta.ts +17 -0
  385. package/interfaces/IProperty.ts +13 -0
  386. package/interfaces/IRegisteredSubjects.ts +12 -0
  387. package/interfaces/ISeedSubjectDraft.ts +17 -0
  388. package/interfaces/ISubject.ts +13 -0
  389. package/interfaces/ISubjectDetail.ts +12 -0
  390. package/mcp/ArtifactResolver.ts +296 -0
  391. package/mcp/index.ts +2 -0
  392. package/package.json +20 -8
  393. package/page-extensions/GlobalComponents.ts +30 -0
  394. package/page-extensions/GoToDeepLink.ts +9 -0
  395. package/page-extensions/LoginFeatures.ts +8 -0
  396. package/page-extensions/SubjectRegistry.ts +32 -0
  397. package/page-extensions/UserSimulation.ts +21 -0
  398. package/page-extensions/WaitEventHandler.ts +20 -0
  399. package/page-overrides/ClickOverride.ts +36 -55
  400. package/page-overrides/FillOverride.ts +59 -73
  401. package/promptCredentials.js +1 -1
  402. package/scripts/Testwise.template.json +1 -1
  403. package/scripts/diagram.js +2267 -0
  404. package/scripts/main.js +84 -63
  405. package/scripts/postinstall.js +55 -42
  406. package/scripts/setup.js +91 -37
  407. package/scripts/sync.js +767 -748
  408. package/services/ConfigBuilder.ts +24 -0
  409. package/services/IndiciumApi.service.ts +44 -6
  410. package/services/Logger.ts +40 -0
  411. package/templates/copilot-instructions.md +130 -0
  412. package/templates/mcp.json +9 -0
  413. package/templates/testwise-test-expert.agent.md +453 -0
  414. package/tests/tsconfig.json +12 -0
  415. package/tsconfig.json +6 -2
  416. package/types/Components.ts +17 -2
  417. package/types/LocatorType.ts +5 -0
  418. package/types/PollTypes.ts +8 -0
  419. package/types/Test.ts +18 -0
  420. package/types/Universal.ts +12 -0
  421. package/types/index.ts +2 -0
  422. package/dist/interfaces/IStoredTestResults.d.ts +0 -5
  423. package/dist/interfaces/IStoredTestResults.js +0 -2
  424. package/dist/interfaces/IStoredTestResults.js.map +0 -1
  425. package/dist/templates/test-artifacts/SubjectPageBase.d.ts +0 -5
  426. package/dist/templates/test-artifacts/SubjectPageBase.js +0 -6
  427. package/dist/templates/test-artifacts/SubjectPageBase.js.map +0 -1
  428. package/dist/templates/test-artifacts/screens/index.d.ts +0 -1
  429. package/dist/templates/test-artifacts/screens/index.js +0 -2
  430. package/dist/templates/test-artifacts/screens/index.js.map +0 -1
  431. package/dist/templates/test-artifacts/subjects/index.d.ts +0 -1
  432. package/dist/templates/test-artifacts/subjects/index.js +0 -2
  433. package/dist/templates/test-artifacts/subjects/index.js.map +0 -1
  434. package/interfaces/IStoredTestResults.ts +0 -6
@@ -1,22 +1,54 @@
1
1
  import { EventEmitter } from 'node:events';
2
2
  import { testwiseConfig } from '../services/ConfigBuilder.js';
3
3
 
4
- const timeout = testwiseConfig().get<number>('featureSettings.InflightRequests.waitTimeout') ?? 5000;
4
+ /**
5
+ * Tracks in-flight XHR requests made by the Thinkwise application and blocks
6
+ * test execution until the network has been idle for a short stability window.
7
+ *
8
+ * **Why this exists:** The Thinkwise Platform performs fire-and-forget XHR calls
9
+ * for things like navigation, saves, and data loads. Raw Playwright `waitFor*`
10
+ * helpers don't know about these — tests that proceed too early will act on
11
+ * stale data or a half-rendered screen. `FlightTracker` listens to every
12
+ * request/response cycle and exposes `waitToContinue()` which returns only
13
+ * once all tracked requests have finished AND the page has been quiet for at
14
+ * least `stabilityTime` milliseconds.
15
+ *
16
+ * **How to use it in tests:** You don't — it is wired up automatically inside
17
+ * `SubjectNavigator.navigateTo()`, `ClickOverride`, and `FillOverride`. You
18
+ * only need to know it exists if you are writing a new page-extension or
19
+ * override that performs navigation.
20
+ *
21
+ * @example
22
+ * // Inside a page-override or page-extension:
23
+ * const tracker = new FlightTracker();
24
+ * page.on('request', req => tracker.handleRequestStarted(req.url(), req.resourceType()));
25
+ * page.on('response', res => tracker.handleRequestFinished(res.request().url()));
26
+ * await myAction();
27
+ * await tracker.waitToContinue();
28
+ */
29
+ const minTimeout = 30000;
30
+ const timeout = Math.max(testwiseConfig().get<number>('featureSettings.InflightRequests.waitTimeout') ?? 0, minTimeout);
31
+
5
32
  const stabilityTime = 150;
6
33
 
7
34
  export class FlightTracker {
8
35
  public requestsInFlight: number = 0;
9
- private activeRequests = new Set<string>();
36
+ private activeRequests = new Map<string, number>();
10
37
  public eventEmitter: EventEmitter = new EventEmitter();
11
38
 
12
39
  /**
13
- * Filters out non-functional "noise" requests that shouldn't block test execution.
40
+ * Returns true for XHR requests that should block test execution.
41
+ * Filters out non-XHR traffic and known noise endpoints.
14
42
  */
15
- public isEssentialRequest(url: string): boolean {
43
+ public isEssentialRequest(url: string, resourceType: string): boolean {
44
+ if (resourceType !== 'xhr') return false;
45
+
16
46
  const noisePatterns = [
17
- '.download_icon',
18
- '.download_list_bar_grp_icon',
19
- '.download_form_next_grp_icon',
47
+ '/detect_change(',
48
+ '/set_gui_start_use_log_session',
49
+ 'download_icon',
50
+ 'download_list_bar_grp_icon',
51
+ 'download_form_next_grp_icon',
20
52
  '/badge()',
21
53
  'universal_background_picture',
22
54
  'i_ui_theme'
@@ -25,17 +57,44 @@ export class FlightTracker {
25
57
  return !noisePatterns.some((pattern) => url.includes(pattern));
26
58
  }
27
59
 
28
- public handleRequestStarted = (url: string) => {
29
- if (this.isEssentialRequest(url)) {
30
- this.activeRequests.add(url);
31
- this.requestsInFlight = this.activeRequests.size;
60
+ public handleRequestStarted = (url: string, resourceType: string) => {
61
+ if (this.isEssentialRequest(url, resourceType)) {
62
+ const wasIdle = this.activeRequests.size === 0;
63
+ this.activeRequests.set(url, (this.activeRequests.get(url) ?? 0) + 1);
64
+ this.requestsInFlight++;
65
+ if (wasIdle) this.eventEmitter.emit('active');
66
+ }
67
+ };
68
+
69
+ public reset = (): void => {
70
+ this.activeRequests.clear();
71
+ this.requestsInFlight = 0;
72
+ };
73
+
74
+ public handleRequestFailed = (url: string) => {
75
+ const count = this.activeRequests.get(url);
76
+ if (count !== undefined) {
77
+ if (count <= 1) {
78
+ this.activeRequests.delete(url);
79
+ } else {
80
+ this.activeRequests.set(url, count - 1);
81
+ }
82
+ this.requestsInFlight = Math.max(0, this.requestsInFlight - 1);
83
+ if (this.requestsInFlight === 0) {
84
+ this.eventEmitter.emit('idle');
85
+ }
32
86
  }
33
87
  };
34
88
 
35
89
  public handleRequestFinished = (url: string) => {
36
- if (this.isEssentialRequest(url)) {
37
- this.activeRequests.delete(url);
38
- this.requestsInFlight = this.activeRequests.size;
90
+ const count = this.activeRequests.get(url);
91
+ if (count !== undefined) {
92
+ if (count <= 1) {
93
+ this.activeRequests.delete(url);
94
+ } else {
95
+ this.activeRequests.set(url, count - 1);
96
+ }
97
+ this.requestsInFlight = Math.max(0, this.requestsInFlight - 1);
39
98
  if (this.requestsInFlight === 0) {
40
99
  this.eventEmitter.emit('idle');
41
100
  }
@@ -64,14 +123,14 @@ export class FlightTracker {
64
123
  this.eventEmitter.on('idle', checkIdle);
65
124
  });
66
125
 
67
- const timeoutPromise = new Promise<void>((_, reject) => {
126
+ const timeoutPromise = new Promise<void>((resolve) => {
68
127
  timeoutId = setTimeout(() => {
69
- const pending = Array.from(this.activeRequests).join('\n -> ');
70
- reject(
71
- new Error(
72
- `Timeout waiting for ${this.requestsInFlight} requests to complete (${timeout}ms).\nPending Essential Requests:\n -> ${pending}`
73
- )
128
+ const pending = Array.from(this.activeRequests.keys()).join('\n -> ');
129
+ console.warn(
130
+ `FlightTracker: timed out after ${timeout}ms waiting for ${this.requestsInFlight} request(s) to complete.\nPending Essential Requests:\n -> ${pending}\nContinuing test execution.`
74
131
  );
132
+ this.reset();
133
+ resolve();
75
134
  }, timeout);
76
135
  });
77
136
 
@@ -83,4 +142,34 @@ export class FlightTracker {
83
142
  this.eventEmitter.removeAllListeners('idle');
84
143
  }
85
144
  };
145
+
146
+ /**
147
+ * For use after hash-based SPA navigation. Waits for the SPA to begin firing
148
+ * XHR requests (within `spaStartupTimeout`), then waits for all of them to
149
+ * settle. If no requests appear within the startup window the page is
150
+ * considered already loaded.
151
+ */
152
+ public waitForNavigationToSettle = async (spaStartupTimeout = 3000): Promise<void> => {
153
+ if (this.requestsInFlight > 0) {
154
+ return this.waitToContinue();
155
+ }
156
+
157
+ await new Promise<void>((resolve) => {
158
+ const timer = setTimeout(() => {
159
+ this.eventEmitter.off('active', onActive);
160
+ resolve();
161
+ }, spaStartupTimeout);
162
+
163
+ const onActive = () => {
164
+ clearTimeout(timer);
165
+ resolve();
166
+ };
167
+
168
+ this.eventEmitter.once('active', onActive);
169
+ });
170
+
171
+ if (this.requestsInFlight > 0) {
172
+ await this.waitToContinue();
173
+ }
174
+ };
86
175
  }
@@ -2,6 +2,19 @@ import { EventEmitter } from 'node:events';
2
2
  import type { Page, Response } from '@playwright/test';
3
3
  import { testwiseConfig } from '../services/ConfigBuilder.js';
4
4
 
5
+ /**
6
+ * Waits for a specific response URL pattern before allowing test execution
7
+ * to continue. Used when you need to block until a known async API response
8
+ * has arrived, as opposed to waiting for XHR idle (which `FlightTracker` does).
9
+ *
10
+ * Attached to the page as `page.waitEventHandler` by the `WaitEventHandler`
11
+ * page extension. Call `page.waitEventHandler.waitForUrl(pattern)` to block
12
+ * until a response matching that URL has been received.
13
+ *
14
+ * @example
15
+ * // Wait for a specific background endpoint before asserting:
16
+ * await page.waitEventHandler.waitForUrl('/api/employees/load');
17
+ */
5
18
  export class GlobalWaitEventHandler {
6
19
  private _canContinue: boolean = true;
7
20
  private _eventEmitter: EventEmitter = new EventEmitter();
@@ -9,10 +9,22 @@ import { pollUntil } from './Poll.js';
9
9
  const dirname = path.dirname(fileURLToPath(import.meta.url));
10
10
  const configFixture = JSON.parse(fs.readFileSync(path.resolve(dirname, '../../config.json'), 'utf-8'));
11
11
 
12
+ /**
13
+ * Handles authentication against the Thinkwise Indicium API and the
14
+ * web application login screen.
15
+ *
16
+ * Exposed on the page fixture via `LoginFeatures` as `page.logIn()`,
17
+ * `page.logInWithCredentials()`, `page.logInWithOptions()`, and `page.logOut()`.
18
+ * You do not instantiate `LoginHelper` directly in tests.
19
+ *
20
+ * Credentials are read from `Testwise.json` (`environmentSettings.username`
21
+ * and `environmentSettings.password`) by default, and can be overridden
22
+ * per-call via `logInWithCredentials()` or `logInWithOptions()`.
23
+ */
12
24
  export class LoginHelper {
13
25
  private _page: Page;
14
- protected serviceUrl = String(testwiseConfig().get('environmentSettings.serviceUrl'));
15
- protected metaEndpoint = String(testwiseConfig().get('environmentSettings.metaEndpoint'));
26
+ protected serviceUrl = String(testwiseConfig().get('environmentSettings.serviceUrl')).replace(/\/+$/, '');
27
+ protected metaEndpoint = String(testwiseConfig().get('environmentSettings.metaEndpoint')).replace(/\/+$/, '');
16
28
 
17
29
  constructor(page: Page) {
18
30
  if (!this.serviceUrl || this.serviceUrl === 'undefined') throw new Error('Service URL not found');
@@ -56,20 +68,23 @@ export class LoginHelper {
56
68
  }
57
69
 
58
70
  /**
59
- * Navigate to the home page and wait for the menu to load
71
+ * Navigate to the home page and wait for the menu to load.
60
72
  */
61
73
  private async navigateHomeAndWaitForMenuToLoad() {
62
- const baseUrl = testwiseConfig().get<string>('environmentSettings.baseUrl');
74
+ const baseUrl = testwiseConfig().get<string>('environmentSettings.baseUrl')?.replace(/\/+$/, '');
75
+ const minimumTimeout = 60000;
76
+
63
77
  if (!baseUrl) {
64
78
  throw new Error('Base URL is not defined in the configuration.');
65
79
  }
66
- await this._page.goto(baseUrl);
67
80
 
68
- await this._page.route('**/i_ui_menu?**', (route) => {
69
- route.continue();
70
- });
81
+ let timeout = Number(testwiseConfig().get<string | number>('featureSettings.other.loginTimeout') ?? minimumTimeout);
71
82
 
72
- const timeout = Number(testwiseConfig().get<string | number>('featureSettings.other.loginTimeout') ?? 30_000);
83
+ if (Number.isNaN(timeout) || timeout < minimumTimeout) {
84
+ timeout = minimumTimeout;
85
+ }
86
+
87
+ await this._page.goto(baseUrl);
73
88
 
74
89
  await pollUntil(async () => this._page.url().includes('#application='), {
75
90
  timeout,
@@ -93,8 +108,8 @@ export class LoginHelper {
93
108
  }
94
109
 
95
110
  if (serviceUrl && metaEndpoint) {
96
- this.serviceUrl = serviceUrl;
97
- this.metaEndpoint = metaEndpoint;
111
+ this.serviceUrl = serviceUrl.replace(/\/+$/, '');
112
+ this.metaEndpoint = metaEndpoint.replace(/\/+$/, '');
98
113
  }
99
114
 
100
115
  const response = await this._page.request.post(`${this.serviceUrl}/account/api/login`, {
@@ -171,6 +186,10 @@ export class LoginHelper {
171
186
  });
172
187
  }
173
188
 
189
+ /**
190
+ * Logs out the current session by POSTing to the logout endpoint (accepts 204 or 401
191
+ * as valid responses), then clears all browser cookies.
192
+ */
174
193
  public async logOut() {
175
194
  const response = await this._page.request.post(`${this.serviceUrl}/account/api/logout`);
176
195
 
@@ -188,6 +207,14 @@ export class UserPreferences {
188
207
  public readonly guiApplAlias = String(testwiseConfig().get<string>('environmentSettings.guiApplAlias'));
189
208
  public readonly url: string;
190
209
 
210
+ /**
211
+ * Initialises the `UserPreferences` service, resolving the service URL, meta endpoint,
212
+ * and GUI application alias from config (overridable via optional parameters) and
213
+ * constructing the full Indicium endpoint URL.
214
+ * @param requestContext - The Playwright `Page` used to make API requests.
215
+ * @param serviceUrl - Optional override for the service URL from config.
216
+ * @param metaEndpoint - Optional override for the meta endpoint from config.
217
+ */
191
218
  constructor(requestContext: Page, serviceUrl?: string, metaEndpoint?: string) {
192
219
  this._page = requestContext;
193
220
 
@@ -198,9 +225,14 @@ export class UserPreferences {
198
225
  if (!metaEndpoint) throw new Error('Meta endpoint not found or is empty');
199
226
  if (!this.guiApplAlias) throw new Error('GUI application alias not found or is empty');
200
227
 
201
- this.url = `${serviceUrl}/${metaEndpoint}/${this.guiApplAlias}`;
228
+ this.url = `${serviceUrl.replace(/\/+$/, '')}/${metaEndpoint.replace(/\/+$/, '')}/${this.guiApplAlias}`;
202
229
  }
203
230
 
231
+ /**
232
+ * Activates a specific user preference configuration for the current session by POSTing
233
+ * to the `set_up_configuration` endpoint with the given configuration ID.
234
+ * @param upConfigurationId - The ID of the user preference configuration to activate.
235
+ */
204
236
  public async run(upConfigurationId: number) {
205
237
  const fullUrl = `${this.url}/set_up_configuration`;
206
238
 
@@ -211,6 +243,11 @@ export class UserPreferences {
211
243
  await this._page.request.post(fullUrl, { headers: { 'Content-Type': 'application/json; charset=utf-8' }, data });
212
244
  }
213
245
 
246
+ /**
247
+ * Disables all active user preferences for the current session by POSTing to the
248
+ * `disable_up` endpoint.
249
+ * @returns The raw Playwright `APIResponse`.
250
+ */
214
251
  public async disable(): Promise<APIResponse> {
215
252
  const fullUrl = `${this.url}/disable_up`;
216
253
 
@@ -1,7 +1,29 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
 
4
+ /**
5
+ * Locates the root directory of the **consumer project** (the project that has
6
+ * `@thinkwise/testwise` installed as a dependency) at runtime.
7
+ *
8
+ * **Why this exists:** Testwise runs from inside `node_modules` but needs to
9
+ * read and write files that belong to the consuming project (e.g.
10
+ * `registeredSubjects.json`, `Testwise.json`). Simply using `process.cwd()`
11
+ * is unreliable when scripts are invoked from sub-directories. This class
12
+ * walks up the directory tree looking for the first `package.json` whose
13
+ * `name` is NOT `@thinkwise/testwise`, which is guaranteed to be the consumer
14
+ * project root.
15
+ *
16
+ * **How to use it:** Inject it into any pipeline helper that needs to write
17
+ * to the consumer project. `PipelinePaths` already does this — you rarely
18
+ * need to instantiate `PathResolver` directly.
19
+ */
4
20
  export class PathResolver {
21
+ /**
22
+ * Walks up the directory tree from `process.cwd()` to find the nearest `package.json`
23
+ * whose `name` is not `@thinkwise/testwise`, returning that directory as the consumer
24
+ * project root. Falls back to `process.cwd()` if no such package is found.
25
+ * @returns Absolute path to the consumer project's root directory.
26
+ */
5
27
  public getConsumerRootDirectory(): string {
6
28
  let directory = process.cwd();
7
29
  let lastDir = '';
package/helpers/Poll.ts CHANGED
@@ -1,5 +1,17 @@
1
- import type { PollOptions } from '../types/PollTypes.ts';
1
+ import type { PollOptions } from '../types/PollTypes.js';
2
2
 
3
+ /**
4
+ * Repeatedly calls `fn` at a configurable interval until the optional `predicate` returns
5
+ * truthy or the `timeout` is exceeded, at which point it throws.
6
+ * `onTick` is called with the last value and elapsed time after each failing attempt.
7
+ * @param fn - The async or sync function to poll.
8
+ * @param opts.timeout - Maximum wait time in milliseconds (default `10 000`).
9
+ * @param opts.interval - Polling interval in milliseconds (default `200`).
10
+ * @param opts.predicate - Returns `true` when the result is acceptable (default: truthy check).
11
+ * @param opts.onTick - Called after each failing attempt with the last value and elapsed ms.
12
+ * @returns The first value for which `predicate` returns `true`.
13
+ * @throws If `timeout` is exceeded before `predicate` returns `true`.
14
+ */
3
15
  export async function pollUntil<T>(fn: () => Promise<T> | T, opts: PollOptions<T> = {}): Promise<T> {
4
16
  const timeout = opts.timeout ?? 10_000;
5
17
  const interval = opts.interval ?? 200;
@@ -1,10 +1,22 @@
1
- // Escapes characters with special meaning in regexes.
1
+ /**
2
+ * Escapes all characters with special meaning in regular expressions so that `input`
3
+ * can be safely embedded inside a `RegExp` constructor without unintended pattern matching.
4
+ * @param input - The raw string to escape.
5
+ * @returns The escaped string.
6
+ */
2
7
  export function escapeRegex(input: string): string {
3
8
  return input.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
4
9
  }
5
10
 
6
- // Exact match, case-insensitive, Unicode-safe.
7
- // By default trims the input; set trim=false for truly literal.
11
+ /**
12
+ * Builds a case-insensitive, Unicode-safe `RegExp` that exactly matches `input`.
13
+ * Optionally trims leading/trailing whitespace and collapses internal whitespace runs
14
+ * to a single space to match typical UI text normalization.
15
+ * @param input - The text to match exactly.
16
+ * @param opts.trim - Trim leading/trailing whitespace before matching (default `true`).
17
+ * @param opts.collapseWhitespace - Collapse runs of whitespace to a single space (default `false`).
18
+ * @returns A case-insensitive `RegExp` anchored with `^` and `$`.
19
+ */
8
20
  export function exactTextRegex(input: string, opts?: { trim?: boolean; collapseWhitespace?: boolean }) {
9
21
  const { trim = true, collapseWhitespace = false } = opts ?? {};
10
22
  let s = trim ? input.trim() : input;
@@ -0,0 +1,57 @@
1
+ import type { Page } from '@playwright/test';
2
+ import { FlightTracker } from './FlightTracker.js';
3
+
4
+ /**
5
+ * Navigates the browser to a Thinkwise subject deep-link URL and waits for
6
+ * the application to fully settle before returning control to the test.
7
+ *
8
+ * **Why this exists:** Calling `page.goto()` directly does not account for
9
+ * the asynchronous XHR requests that the Thinkwise app fires after a navigation
10
+ * event. Tests that act immediately after a bare `goto` frequently encounter
11
+ * loading spinners, empty grids, or incomplete form data. `SubjectNavigator`
12
+ * wraps navigation in a `FlightTracker` session so the test only continues
13
+ * once the network is truly idle.
14
+ *
15
+ * **How to use it:** You typically don't call this directly — it is used
16
+ * internally by the generated subject class `goTo()` methods. If you need
17
+ * to navigate imperatively in a test, prefer `page.subject.MySubjectClass.goTo()`.
18
+ *
19
+ * @example
20
+ * // Inside a generated subject class:
21
+ * const navigator = new SubjectNavigator(page);
22
+ * await navigator.navigateTo('subjects/Employee/Editable1/Main');
23
+ */
24
+ export class SubjectNavigator {
25
+ private readonly _page: Page;
26
+
27
+ constructor(page: Page) {
28
+ this._page = page;
29
+ }
30
+
31
+ public async navigateTo(url: string): Promise<void> {
32
+ const flightTracker = new FlightTracker();
33
+
34
+ const onRequest = (request: import('@playwright/test').Request) => {
35
+ flightTracker.handleRequestStarted(request.url(), request.resourceType());
36
+ };
37
+ const onResponse = (response: import('@playwright/test').Response) => {
38
+ flightTracker.handleRequestFinished(response.request().url());
39
+ };
40
+ const onRequestFailed = (request: import('@playwright/test').Request) => {
41
+ flightTracker.handleRequestFailed(request.url());
42
+ };
43
+
44
+ this._page.on('request', onRequest);
45
+ this._page.on('response', onResponse);
46
+ this._page.on('requestfailed', onRequestFailed);
47
+
48
+ try {
49
+ await this._page.goToDeepLink(url);
50
+ await flightTracker.waitForNavigationToSettle();
51
+ } finally {
52
+ this._page.off('request', onRequest);
53
+ this._page.off('response', onResponse);
54
+ this._page.off('requestfailed', onRequestFailed);
55
+ }
56
+ }
57
+ }
@@ -2,6 +2,20 @@ import type { Page } from '@playwright/test';
2
2
  import { testwiseConfig } from '../services/ConfigBuilder.js';
3
3
  import { pollUntil } from './Poll.js';
4
4
 
5
+ /**
6
+ * Simulates switching the active user identity in the Thinkwise application
7
+ * at runtime, without logging out and back in. Useful for testing
8
+ * role-based access control (RBAC) and user-specific workflows.
9
+ *
10
+ * Exposed on the page fixture via `UserSimulation` as `page.simulateUser()`,
11
+ * `page.getSimulatedUser()`, and `page.stopSimulation()`. You do not
12
+ * instantiate `UserSimulationHelper` directly in tests.
13
+ *
14
+ * @example
15
+ * await page.simulateUser('john.doe@example.com');
16
+ * // ... assert behaviour for this user ...
17
+ * await page.stopSimulation();
18
+ */
5
19
  export class UserSimulationHelper {
6
20
  private _page: Page;
7
21
  private _serviceUrl: string;
package/helpers/index.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './LoginHelper.js';
2
2
  export * from './PathResolver.js';
3
3
  export * from './RegexHelper.js';
4
+ export * from './SubjectNavigator.js';
package/index.ts CHANGED
@@ -17,6 +17,7 @@ export * from './components/index.js';
17
17
  export * from './controls/index.js';
18
18
  export * from './enums/index.js';
19
19
  export * from './helpers/index.js';
20
+ export * from './mcp/index.js';
20
21
  export * from './page-extensions/index.js';
21
22
  export * from './page-overrides/index.js';
22
23
  export * from './services/index.js';
@@ -1,6 +1,18 @@
1
1
  import type { Locator } from '@playwright/test';
2
2
 
3
+ /**
4
+ * Base contract that every `*Objects` class in `components/` and `controls/`
5
+ * must implement.
6
+ *
7
+ * **Why this exists:** Each component is split into two files — a `<Name>.ts`
8
+ * (public API with interaction methods) and a `<Name>Objects.ts` (raw locator
9
+ * accessors). `IComponentObjects` enforces that every `Objects` class exposes
10
+ * the two locators that all Thinkwise screens share: the scoped `context`
11
+ * locator and the page-level `mainHeader` locator used for presence checks.
12
+ */
3
13
  export interface IComponentObjects {
14
+ /** The scoped Playwright `Locator` that roots all locator lookups for this component instance. */
4
15
  context: Locator;
16
+ /** Locator for `main header` — used as a presence anchor to confirm the screen has rendered. */
5
17
  mainHeader: Locator;
6
18
  }
@@ -0,0 +1,17 @@
1
+ import type { SubjectComponents } from '../types/Components.js';
2
+
3
+ /** Metadata for a single property within a generated component schema. */
4
+ export interface IComponentPropertyMeta {
5
+ colId: string;
6
+ elementType: string;
7
+ }
8
+
9
+ /**
10
+ * The full meta file that SchemaGenerator writes alongside each `.json`
11
+ * schema file, and that SubjectComponentGenerator reads back to drive code
12
+ * generation.
13
+ */
14
+ export interface IComponentSchemaMeta {
15
+ componentType: SubjectComponents;
16
+ properties: Record<string, IComponentPropertyMeta>;
17
+ }
@@ -1,4 +1,17 @@
1
+ /**
2
+ * Describes a single field or column on a Thinkwise screen, as returned by
3
+ * the Indicium API and stored in `seed-data/subjects.json`.
4
+ *
5
+ * The `control_type` drives which Testwise control helper gets generated for
6
+ * the property (e.g. `"field"` → `InputFieldControl`, `"lookup"` → `LookupDropdown`).
7
+ */
1
8
  export interface IProperty {
9
+ /** The field or column identifier as defined in the Thinkwise model (e.g. `"employee_id"`). */
2
10
  col: string;
11
+ /**
12
+ * The Thinkwise UI control type for this property.
13
+ * Drives the control class suffix appended in generated subject components.
14
+ * Common values: `"field"`, `"lookup"`, `"dropdown"`, `"checkbox"`, `"date_picker"`, `"combo_box"`.
15
+ */
3
16
  control_type: string;
4
17
  }
@@ -1,5 +1,17 @@
1
+ /**
2
+ * Describes a subject that has been registered in the consumer project's
3
+ * `registeredSubjects.json` file.
4
+ *
5
+ * The `SubjectRegistration` pipeline step reads generated subject classes and
6
+ * writes an entry here for each one. The `SubjectRegistry` page-extension
7
+ * reads this file at test startup to make all subjects available on
8
+ * `page.subject.<ClassName>`.
9
+ */
1
10
  export interface IRegisteredSubjects {
11
+ /** Thinkwise subject identifier (e.g. `"Employee"`). */
2
12
  subject: string;
13
+ /** Optional variant discriminator when the same subject has multiple variants (e.g. `"Editable1"`). */
3
14
  variant?: string;
15
+ /** Screen type context — `"Main"`, `"Popup"`, `"Zoom"`, or `"Detail"`. */
4
16
  screen_type: string;
5
17
  }
@@ -0,0 +1,17 @@
1
+ import type { IProperty } from './IProperty.js';
2
+
3
+ /**
4
+ * Represents a subject as it is built from the Indicium API before properties
5
+ * are fully populated. `properties` is optional here because it is assigned
6
+ * after the initial object is constructed during the build phase.
7
+ *
8
+ * Once written to `subjects.json` and read back via `DataRetriever`, the data
9
+ * is typed as the narrower `ISubject` (which requires `properties`).
10
+ */
11
+ export interface ISeedSubjectDraft {
12
+ subject: string;
13
+ variant: string;
14
+ screentype_context: string;
15
+ screentype_id: string;
16
+ properties?: IProperty[];
17
+ }
@@ -1,9 +1,22 @@
1
1
  import type { IProperty } from './IProperty.js';
2
2
 
3
+ /**
4
+ * Represents a single Thinkwise subject as stored in `seed-data/subjects.json`
5
+ * after the `ModelDataBuilder` pipeline step fetches it from the Indicium API.
6
+ *
7
+ * Each subject maps to one screen variant in the Thinkwise application. The
8
+ * `SubjectClassModelBuilder` reads these records and turns them into generated
9
+ * TypeScript subject classes under `test-artifacts/subjects/`.
10
+ */
3
11
  export interface ISubject {
12
+ /** Internal Thinkwise subject identifier (e.g. `"Employee"`). */
4
13
  subject: string;
14
+ /** Subject variant, used to distinguish multiple configurations of the same subject (e.g. `"Editable1"`). */
5
15
  variant: string;
16
+ /** Human-readable screen context: `"Main"`, `"Popup"`, `"Zoom"`, or `"Detail"`. */
6
17
  screentype_context: string;
18
+ /** Thinkwise screen type identifier used to look up the correct screen schema file. */
7
19
  screentype_id: string;
20
+ /** All field/column properties available on this screen. */
8
21
  properties: IProperty[];
9
22
  }
@@ -0,0 +1,12 @@
1
+ /** Screen context variants produced by the artifact-builder pipeline. */
2
+ export type ScreenContext = 'Main' | 'Popup' | 'Zoom' | 'Detail';
3
+
4
+ /**
5
+ * Describes a single generated subject class that the SubjectRegistration
6
+ * step registers in the SubjectRegistry.
7
+ */
8
+ export interface ISubjectDetail {
9
+ subject: string;
10
+ variant?: string;
11
+ screen: ScreenContext;
12
+ }