@thinkwise/testwise 0.2.62 → 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.
- package/Testwise.ts +35 -0
- package/artifact-builder/ArtifactManager.ts +25 -2
- package/artifact-builder/ComponentClassModelBuilder.ts +148 -0
- package/artifact-builder/InterfaceGenerator.ts +31 -33
- package/artifact-builder/ModelDataBuilder.ts +18 -20
- package/artifact-builder/ModelDataRefiner.ts +23 -3
- package/artifact-builder/SchemaGenerator.ts +45 -35
- package/artifact-builder/ScreenInterfaceRefiner.ts +25 -10
- package/artifact-builder/SelectorBuilder.ts +30 -24
- package/artifact-builder/SubjectClassModelBuilder.ts +209 -0
- package/artifact-builder/SubjectComponentGenerator.ts +67 -246
- package/artifact-builder/SubjectGenerator.ts +117 -230
- package/artifact-builder/SubjectRegistration.ts +41 -32
- package/artifact-builder/TsFileModel.ts +94 -0
- package/artifact-builder/TsFileSerializer.ts +247 -0
- package/artifact-builder/helpers/DataRetriever.ts +64 -27
- package/artifact-builder/helpers/NamingHandler.ts +23 -78
- package/artifact-builder/helpers/PipelinePaths.ts +123 -0
- package/artifact-builder/helpers/Stopwatch.ts +10 -0
- package/artifact-builder/helpers/index.ts +1 -0
- package/artifact-builder/index.ts +4 -0
- package/components/BaseComponentObjects.ts +17 -0
- package/components/action-bar/ActionBar.ts +35 -47
- package/components/action-bar/ActionBarObjects.ts +2 -0
- package/components/action-bar/CustomActionBar.ts +6 -0
- package/components/cardlist/Cardlist.ts +6 -0
- package/components/chart/Chart.ts +6 -0
- package/components/combined-filter/CombinedFilter.ts +9 -0
- package/components/cube-view-bar/CubeViewBar.ts +6 -0
- package/components/export/ExportComponent.ts +12 -0
- package/components/filter/ExcelStyleFilterPopup.ts +83 -10
- package/components/filter/ExcelStyleFilterPopupObjects.ts +29 -3
- package/components/filter/FilterForm.ts +10 -0
- package/components/filter/FilterPopup.ts +30 -9
- package/components/filter/FilterPopupObjects.ts +10 -3
- package/components/filter/FindForm.ts +7 -0
- package/components/filter/ManagePrefilterPopup.ts +11 -0
- package/components/form/Form.ts +16 -0
- package/components/grid/Grid.ts +50 -14
- package/components/grid/GridObjects.ts +0 -15
- package/components/maps/Maps.ts +6 -0
- package/components/menu/ListBarMenuComponent.ts +10 -0
- package/components/pivot-grid/PivotGrid.ts +6 -0
- package/components/pivot-grid/PivotGridFieldList.ts +7 -0
- package/components/pop-up/AllRowsPopUp.ts +12 -0
- package/components/pop-up/PopUpComponent.ts +11 -0
- package/components/prefilter-list/PrefilterList.ts +9 -0
- package/components/preview/Preview.ts +6 -0
- package/components/report-bar/ReportBar.ts +6 -0
- package/components/report-tiles/ReportTiles.ts +6 -0
- package/components/scheduler/Scheduler.ts +6 -0
- package/components/snackbar/SnackBar.ts +12 -0
- package/components/splitter/Splitter.ts +6 -0
- package/components/tab/BaseTab.ts +5 -0
- package/components/tab/DetailTabPage.ts +11 -0
- package/components/tab/Tab.ts +10 -0
- package/components/task/TaskBar.ts +13 -3
- package/components/task/TaskTiles.ts +12 -3
- package/components/topbar/TopBar.ts +10 -0
- package/components/tree-view/TreeView.ts +9 -0
- package/controls/DateControl.ts +47 -9
- package/controls/DateControlObjects.ts +15 -0
- package/controls/FormComboBox.ts +43 -26
- package/controls/FormComboBoxObjects.ts +27 -0
- package/controls/GridColumnControl.ts +35 -4
- package/controls/GridColumnControlObjects.ts +1 -1
- package/controls/InputFieldControl.ts +61 -15
- package/controls/InputFieldControlObjects.ts +19 -0
- package/controls/LookupDropdown.ts +59 -31
- package/controls/LookupDropdownObjects.ts +19 -0
- package/dist/Testwise.js +35 -0
- package/dist/Testwise.js.map +1 -1
- package/dist/artifact-builder/ArtifactManager.d.ts +18 -1
- package/dist/artifact-builder/ArtifactManager.js +24 -2
- package/dist/artifact-builder/ArtifactManager.js.map +1 -1
- package/dist/artifact-builder/ComponentClassModelBuilder.d.ts +22 -0
- package/dist/artifact-builder/ComponentClassModelBuilder.js +115 -0
- package/dist/artifact-builder/ComponentClassModelBuilder.js.map +1 -0
- package/dist/artifact-builder/InterfaceGenerator.d.ts +15 -6
- package/dist/artifact-builder/InterfaceGenerator.js +27 -26
- package/dist/artifact-builder/InterfaceGenerator.js.map +1 -1
- package/dist/artifact-builder/ModelDataBuilder.d.ts +7 -0
- package/dist/artifact-builder/ModelDataBuilder.js +13 -5
- package/dist/artifact-builder/ModelDataBuilder.js.map +1 -1
- package/dist/artifact-builder/ModelDataRefiner.d.ts +18 -1
- package/dist/artifact-builder/ModelDataRefiner.js +18 -3
- package/dist/artifact-builder/ModelDataRefiner.js.map +1 -1
- package/dist/artifact-builder/SchemaGenerator.d.ts +21 -5
- package/dist/artifact-builder/SchemaGenerator.js +38 -26
- package/dist/artifact-builder/SchemaGenerator.js.map +1 -1
- package/dist/artifact-builder/ScreenInterfaceRefiner.d.ts +18 -1
- package/dist/artifact-builder/ScreenInterfaceRefiner.js +23 -9
- package/dist/artifact-builder/ScreenInterfaceRefiner.js.map +1 -1
- package/dist/artifact-builder/SelectorBuilder.d.ts +18 -5
- package/dist/artifact-builder/SelectorBuilder.js +29 -14
- package/dist/artifact-builder/SelectorBuilder.js.map +1 -1
- package/dist/artifact-builder/SubjectClassModelBuilder.d.ts +38 -0
- package/dist/artifact-builder/SubjectClassModelBuilder.js +158 -0
- package/dist/artifact-builder/SubjectClassModelBuilder.js.map +1 -0
- package/dist/artifact-builder/SubjectComponentGenerator.d.ts +25 -14
- package/dist/artifact-builder/SubjectComponentGenerator.js +65 -189
- package/dist/artifact-builder/SubjectComponentGenerator.js.map +1 -1
- package/dist/artifact-builder/SubjectGenerator.d.ts +32 -13
- package/dist/artifact-builder/SubjectGenerator.js +81 -165
- package/dist/artifact-builder/SubjectGenerator.js.map +1 -1
- package/dist/artifact-builder/SubjectRegistration.d.ts +22 -8
- package/dist/artifact-builder/SubjectRegistration.js +29 -14
- package/dist/artifact-builder/SubjectRegistration.js.map +1 -1
- package/dist/artifact-builder/TsFileModel.d.ts +86 -0
- package/dist/artifact-builder/TsFileModel.js +2 -0
- package/dist/artifact-builder/TsFileModel.js.map +1 -0
- package/dist/artifact-builder/TsFileSerializer.d.ts +19 -0
- package/dist/artifact-builder/TsFileSerializer.js +225 -0
- package/dist/artifact-builder/TsFileSerializer.js.map +1 -0
- package/dist/artifact-builder/helpers/DataRetriever.d.ts +22 -3
- package/dist/artifact-builder/helpers/DataRetriever.js +56 -26
- package/dist/artifact-builder/helpers/DataRetriever.js.map +1 -1
- package/dist/artifact-builder/helpers/NamingHandler.d.ts +18 -6
- package/dist/artifact-builder/helpers/NamingHandler.js +20 -61
- package/dist/artifact-builder/helpers/NamingHandler.js.map +1 -1
- package/dist/artifact-builder/helpers/PipelinePaths.d.ts +52 -0
- package/dist/artifact-builder/helpers/PipelinePaths.js +99 -0
- package/dist/artifact-builder/helpers/PipelinePaths.js.map +1 -0
- package/dist/artifact-builder/helpers/Stopwatch.d.ts +10 -0
- package/dist/artifact-builder/helpers/Stopwatch.js +10 -0
- package/dist/artifact-builder/helpers/Stopwatch.js.map +1 -1
- package/dist/artifact-builder/helpers/index.d.ts +1 -0
- package/dist/artifact-builder/helpers/index.js +1 -0
- package/dist/artifact-builder/helpers/index.js.map +1 -1
- package/dist/artifact-builder/index.d.ts +4 -0
- package/dist/artifact-builder/index.js +4 -0
- package/dist/artifact-builder/index.js.map +1 -1
- package/dist/components/BaseComponentObjects.d.ts +17 -0
- package/dist/components/BaseComponentObjects.js +17 -0
- package/dist/components/BaseComponentObjects.js.map +1 -1
- package/dist/components/action-bar/ActionBar.d.ts +21 -24
- package/dist/components/action-bar/ActionBar.js +31 -24
- package/dist/components/action-bar/ActionBar.js.map +1 -1
- package/dist/components/action-bar/ActionBarObjects.d.ts +1 -0
- package/dist/components/action-bar/ActionBarObjects.js +1 -0
- package/dist/components/action-bar/ActionBarObjects.js.map +1 -1
- package/dist/components/action-bar/CustomActionBar.d.ts +6 -0
- package/dist/components/action-bar/CustomActionBar.js +6 -0
- package/dist/components/action-bar/CustomActionBar.js.map +1 -1
- package/dist/components/cardlist/Cardlist.d.ts +6 -0
- package/dist/components/cardlist/Cardlist.js +6 -0
- package/dist/components/cardlist/Cardlist.js.map +1 -1
- package/dist/components/chart/Chart.d.ts +6 -0
- package/dist/components/chart/Chart.js +6 -0
- package/dist/components/chart/Chart.js.map +1 -1
- package/dist/components/combined-filter/CombinedFilter.d.ts +9 -0
- package/dist/components/combined-filter/CombinedFilter.js +9 -0
- package/dist/components/combined-filter/CombinedFilter.js.map +1 -1
- package/dist/components/cube-view-bar/CubeViewBar.d.ts +6 -0
- package/dist/components/cube-view-bar/CubeViewBar.js +6 -0
- package/dist/components/cube-view-bar/CubeViewBar.js.map +1 -1
- package/dist/components/export/ExportComponent.d.ts +12 -0
- package/dist/components/export/ExportComponent.js +12 -0
- package/dist/components/export/ExportComponent.js.map +1 -1
- package/dist/components/filter/ExcelStyleFilterPopup.d.ts +25 -2
- package/dist/components/filter/ExcelStyleFilterPopup.js +60 -6
- package/dist/components/filter/ExcelStyleFilterPopup.js.map +1 -1
- package/dist/components/filter/ExcelStyleFilterPopupObjects.d.ts +8 -1
- package/dist/components/filter/ExcelStyleFilterPopupObjects.js +15 -2
- package/dist/components/filter/ExcelStyleFilterPopupObjects.js.map +1 -1
- package/dist/components/filter/FilterForm.d.ts +10 -0
- package/dist/components/filter/FilterForm.js +10 -0
- package/dist/components/filter/FilterForm.js.map +1 -1
- package/dist/components/filter/FilterPopup.d.ts +22 -4
- package/dist/components/filter/FilterPopup.js +17 -9
- package/dist/components/filter/FilterPopup.js.map +1 -1
- package/dist/components/filter/FilterPopupObjects.d.ts +5 -2
- package/dist/components/filter/FilterPopupObjects.js +5 -2
- package/dist/components/filter/FilterPopupObjects.js.map +1 -1
- package/dist/components/filter/FindForm.d.ts +7 -0
- package/dist/components/filter/FindForm.js +7 -0
- package/dist/components/filter/FindForm.js.map +1 -1
- package/dist/components/filter/ManagePrefilterPopup.d.ts +11 -0
- package/dist/components/filter/ManagePrefilterPopup.js +11 -0
- package/dist/components/filter/ManagePrefilterPopup.js.map +1 -1
- package/dist/components/form/Form.d.ts +16 -0
- package/dist/components/form/Form.js +16 -0
- package/dist/components/form/Form.js.map +1 -1
- package/dist/components/grid/Grid.d.ts +20 -1
- package/dist/components/grid/Grid.js +35 -25
- package/dist/components/grid/Grid.js.map +1 -1
- package/dist/components/grid/GridObjects.d.ts +0 -4
- package/dist/components/grid/GridObjects.js +0 -6
- package/dist/components/grid/GridObjects.js.map +1 -1
- package/dist/components/maps/Maps.d.ts +6 -0
- package/dist/components/maps/Maps.js +6 -0
- package/dist/components/maps/Maps.js.map +1 -1
- package/dist/components/menu/ListBarMenuComponent.d.ts +10 -0
- package/dist/components/menu/ListBarMenuComponent.js +10 -0
- package/dist/components/menu/ListBarMenuComponent.js.map +1 -1
- package/dist/components/pivot-grid/PivotGrid.d.ts +6 -0
- package/dist/components/pivot-grid/PivotGrid.js +6 -0
- package/dist/components/pivot-grid/PivotGrid.js.map +1 -1
- package/dist/components/pivot-grid/PivotGridFieldList.d.ts +7 -0
- package/dist/components/pivot-grid/PivotGridFieldList.js +7 -0
- package/dist/components/pivot-grid/PivotGridFieldList.js.map +1 -1
- package/dist/components/pop-up/AllRowsPopUp.d.ts +12 -0
- package/dist/components/pop-up/AllRowsPopUp.js +12 -0
- package/dist/components/pop-up/AllRowsPopUp.js.map +1 -1
- package/dist/components/pop-up/PopUpComponent.d.ts +11 -0
- package/dist/components/pop-up/PopUpComponent.js +11 -0
- package/dist/components/pop-up/PopUpComponent.js.map +1 -1
- package/dist/components/prefilter-list/PrefilterList.d.ts +9 -0
- package/dist/components/prefilter-list/PrefilterList.js +9 -0
- package/dist/components/prefilter-list/PrefilterList.js.map +1 -1
- package/dist/components/preview/Preview.d.ts +6 -0
- package/dist/components/preview/Preview.js +6 -0
- package/dist/components/preview/Preview.js.map +1 -1
- package/dist/components/report-bar/ReportBar.d.ts +6 -0
- package/dist/components/report-bar/ReportBar.js +6 -0
- package/dist/components/report-bar/ReportBar.js.map +1 -1
- package/dist/components/report-tiles/ReportTiles.d.ts +6 -0
- package/dist/components/report-tiles/ReportTiles.js +6 -0
- package/dist/components/report-tiles/ReportTiles.js.map +1 -1
- package/dist/components/scheduler/Scheduler.d.ts +6 -0
- package/dist/components/scheduler/Scheduler.js +6 -0
- package/dist/components/scheduler/Scheduler.js.map +1 -1
- package/dist/components/snackbar/SnackBar.d.ts +12 -0
- package/dist/components/snackbar/SnackBar.js +12 -0
- package/dist/components/snackbar/SnackBar.js.map +1 -1
- package/dist/components/splitter/Splitter.d.ts +6 -0
- package/dist/components/splitter/Splitter.js +6 -0
- package/dist/components/splitter/Splitter.js.map +1 -1
- package/dist/components/tab/BaseTab.d.ts +5 -0
- package/dist/components/tab/BaseTab.js +5 -0
- package/dist/components/tab/BaseTab.js.map +1 -1
- package/dist/components/tab/DetailTabPage.d.ts +11 -0
- package/dist/components/tab/DetailTabPage.js +11 -0
- package/dist/components/tab/DetailTabPage.js.map +1 -1
- package/dist/components/tab/Tab.d.ts +10 -0
- package/dist/components/tab/Tab.js +10 -0
- package/dist/components/tab/Tab.js.map +1 -1
- package/dist/components/task/TaskBar.d.ts +12 -2
- package/dist/components/task/TaskBar.js +13 -3
- package/dist/components/task/TaskBar.js.map +1 -1
- package/dist/components/task/TaskTiles.d.ts +11 -2
- package/dist/components/task/TaskTiles.js +12 -3
- package/dist/components/task/TaskTiles.js.map +1 -1
- package/dist/components/topbar/TopBar.d.ts +10 -0
- package/dist/components/topbar/TopBar.js +10 -0
- package/dist/components/topbar/TopBar.js.map +1 -1
- package/dist/components/tree-view/TreeView.d.ts +9 -0
- package/dist/components/tree-view/TreeView.js +9 -0
- package/dist/components/tree-view/TreeView.js.map +1 -1
- package/dist/controls/DateControl.d.ts +40 -2
- package/dist/controls/DateControl.js +24 -7
- package/dist/controls/DateControl.js.map +1 -1
- package/dist/controls/DateControlObjects.d.ts +8 -1
- package/dist/controls/DateControlObjects.js +8 -1
- package/dist/controls/DateControlObjects.js.map +1 -1
- package/dist/controls/FormComboBox.d.ts +30 -0
- package/dist/controls/FormComboBox.js +19 -16
- package/dist/controls/FormComboBox.js.map +1 -1
- package/dist/controls/FormComboBoxObjects.d.ts +12 -1
- package/dist/controls/FormComboBoxObjects.js +15 -1
- package/dist/controls/FormComboBoxObjects.js.map +1 -1
- package/dist/controls/GridColumnControl.d.ts +30 -0
- package/dist/controls/GridColumnControl.js +13 -4
- package/dist/controls/GridColumnControl.js.map +1 -1
- package/dist/controls/GridColumnControlObjects.js +1 -1
- package/dist/controls/GridColumnControlObjects.js.map +1 -1
- package/dist/controls/InputFieldControl.d.ts +50 -3
- package/dist/controls/InputFieldControl.js +40 -11
- package/dist/controls/InputFieldControl.js.map +1 -1
- package/dist/controls/InputFieldControlObjects.d.ts +10 -1
- package/dist/controls/InputFieldControlObjects.js +10 -1
- package/dist/controls/InputFieldControlObjects.js.map +1 -1
- package/dist/controls/LookupDropdown.d.ts +29 -0
- package/dist/controls/LookupDropdown.js +36 -25
- package/dist/controls/LookupDropdown.js.map +1 -1
- package/dist/controls/LookupDropdownObjects.d.ts +10 -0
- package/dist/controls/LookupDropdownObjects.js +11 -0
- package/dist/controls/LookupDropdownObjects.js.map +1 -0
- package/dist/enums/ElementTypes.d.ts +18 -0
- package/dist/enums/ElementTypes.js +18 -0
- package/dist/enums/ElementTypes.js.map +1 -1
- package/dist/enums/ExportFormat.d.ts +8 -0
- package/dist/enums/ExportFormat.js +8 -0
- package/dist/enums/ExportFormat.js.map +1 -1
- package/dist/enums/LogLevel.d.ts +17 -0
- package/dist/enums/LogLevel.js +17 -1
- package/dist/enums/LogLevel.js.map +1 -1
- package/dist/enums/index.d.ts +1 -0
- package/dist/enums/index.js +1 -0
- package/dist/enums/index.js.map +1 -1
- package/dist/helpers/ConfigChecker.d.ts +13 -0
- package/dist/helpers/ConfigChecker.js +13 -0
- package/dist/helpers/ConfigChecker.js.map +1 -1
- package/dist/helpers/Ensure.d.ts +13 -0
- package/dist/helpers/Ensure.js +13 -0
- package/dist/helpers/Ensure.js.map +1 -1
- package/dist/helpers/FlightTracker.d.ts +13 -3
- package/dist/helpers/FlightTracker.js +103 -17
- package/dist/helpers/FlightTracker.js.map +1 -1
- package/dist/helpers/GlobalWaitEventHandler.d.ts +13 -0
- package/dist/helpers/GlobalWaitEventHandler.js +13 -0
- package/dist/helpers/GlobalWaitEventHandler.js.map +1 -1
- package/dist/helpers/LoginHelper.d.ts +35 -1
- package/dist/helpers/LoginHelper.js +46 -11
- package/dist/helpers/LoginHelper.js.map +1 -1
- package/dist/helpers/PathResolver.d.ts +22 -0
- package/dist/helpers/PathResolver.js +22 -0
- package/dist/helpers/PathResolver.js.map +1 -1
- package/dist/helpers/Poll.d.ts +13 -1
- package/dist/helpers/Poll.js +12 -0
- package/dist/helpers/Poll.js.map +1 -1
- package/dist/helpers/RegexHelper.d.ts +15 -0
- package/dist/helpers/RegexHelper.js +15 -3
- package/dist/helpers/RegexHelper.js.map +1 -1
- package/dist/helpers/SubjectNavigator.d.ts +26 -0
- package/dist/helpers/SubjectNavigator.js +51 -0
- package/dist/helpers/SubjectNavigator.js.map +1 -0
- package/dist/helpers/UserSimulationHelper.d.ts +14 -0
- package/dist/helpers/UserSimulationHelper.js +14 -0
- package/dist/helpers/UserSimulationHelper.js.map +1 -1
- package/dist/helpers/index.d.ts +1 -0
- package/dist/helpers/index.js +1 -0
- package/dist/helpers/index.js.map +1 -1
- package/dist/index.d.ts +6 -20
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces/IComponentObjects.d.ts +12 -0
- package/dist/interfaces/IComponentSchemaMeta.d.ts +15 -0
- package/dist/interfaces/IComponentSchemaMeta.js +2 -0
- package/dist/interfaces/IComponentSchemaMeta.js.map +1 -0
- package/dist/interfaces/IProperty.d.ts +13 -0
- package/dist/interfaces/IRegisteredSubjects.d.ts +12 -0
- package/dist/interfaces/ISeedSubjectDraft.d.ts +16 -0
- package/dist/interfaces/ISeedSubjectDraft.js +2 -0
- package/dist/interfaces/ISeedSubjectDraft.js.map +1 -0
- package/dist/interfaces/ISubject.d.ts +13 -0
- package/dist/interfaces/ISubjectDetail.d.ts +11 -0
- package/dist/interfaces/ISubjectDetail.js +2 -0
- package/dist/interfaces/ISubjectDetail.js.map +1 -0
- package/dist/mcp/ArtifactResolver.d.ts +152 -0
- package/dist/mcp/ArtifactResolver.js +232 -0
- package/dist/mcp/ArtifactResolver.js.map +1 -0
- package/dist/mcp/index.d.ts +2 -0
- package/dist/mcp/index.js +2 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/page-extensions/GlobalComponents.d.ts +30 -0
- package/dist/page-extensions/GlobalComponents.js +30 -0
- package/dist/page-extensions/GlobalComponents.js.map +1 -1
- package/dist/page-extensions/GoToDeepLink.d.ts +9 -0
- package/dist/page-extensions/GoToDeepLink.js +9 -0
- package/dist/page-extensions/GoToDeepLink.js.map +1 -1
- package/dist/page-extensions/LoginFeatures.d.ts +8 -0
- package/dist/page-extensions/LoginFeatures.js +8 -0
- package/dist/page-extensions/LoginFeatures.js.map +1 -1
- package/dist/page-extensions/SubjectRegistry.d.ts +31 -0
- package/dist/page-extensions/SubjectRegistry.js +31 -0
- package/dist/page-extensions/SubjectRegistry.js.map +1 -1
- package/dist/page-extensions/UserSimulation.d.ts +21 -0
- package/dist/page-extensions/UserSimulation.js +21 -0
- package/dist/page-extensions/UserSimulation.js.map +1 -1
- package/dist/page-extensions/WaitEventHandler.d.ts +20 -0
- package/dist/page-extensions/WaitEventHandler.js +20 -0
- package/dist/page-extensions/WaitEventHandler.js.map +1 -1
- package/dist/page-overrides/ClickOverride.d.ts +23 -2
- package/dist/page-overrides/ClickOverride.js +34 -50
- package/dist/page-overrides/ClickOverride.js.map +1 -1
- package/dist/page-overrides/FillOverride.d.ts +23 -0
- package/dist/page-overrides/FillOverride.js +46 -66
- package/dist/page-overrides/FillOverride.js.map +1 -1
- package/dist/services/ConfigBuilder.d.ts +24 -0
- package/dist/services/ConfigBuilder.js +24 -0
- package/dist/services/ConfigBuilder.js.map +1 -1
- package/dist/services/IndiciumApi.service.d.ts +26 -0
- package/dist/services/IndiciumApi.service.js +40 -5
- package/dist/services/IndiciumApi.service.js.map +1 -1
- package/dist/services/Logger.d.ts +13 -0
- package/dist/services/Logger.js +39 -0
- package/dist/services/Logger.js.map +1 -1
- package/dist/types/Components.d.ts +18 -1
- package/dist/types/Components.js +0 -1
- package/dist/types/Components.js.map +1 -1
- package/dist/types/LocatorType.d.ts +5 -0
- package/dist/types/LocatorType.js +2 -0
- package/dist/types/LocatorType.js.map +1 -0
- package/dist/types/PollTypes.d.ts +8 -0
- package/dist/types/Test.d.ts +18 -0
- package/dist/types/Universal.d.ts +12 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -1
- package/enums/ElementTypes.ts +18 -0
- package/enums/ExportFormat.ts +8 -0
- package/enums/LogLevel.ts +17 -1
- package/enums/index.ts +1 -0
- package/helpers/ConfigChecker.ts +13 -0
- package/helpers/Ensure.ts +13 -0
- package/helpers/FlightTracker.ts +109 -20
- package/helpers/GlobalWaitEventHandler.ts +13 -0
- package/helpers/LoginHelper.ts +49 -12
- package/helpers/PathResolver.ts +22 -0
- package/helpers/Poll.ts +13 -1
- package/helpers/RegexHelper.ts +15 -3
- package/helpers/SubjectNavigator.ts +57 -0
- package/helpers/UserSimulationHelper.ts +14 -0
- package/helpers/index.ts +1 -0
- package/index.ts +1 -0
- package/interfaces/IComponentObjects.ts +12 -0
- package/interfaces/IComponentSchemaMeta.ts +17 -0
- package/interfaces/IProperty.ts +13 -0
- package/interfaces/IRegisteredSubjects.ts +12 -0
- package/interfaces/ISeedSubjectDraft.ts +17 -0
- package/interfaces/ISubject.ts +13 -0
- package/interfaces/ISubjectDetail.ts +12 -0
- package/mcp/ArtifactResolver.ts +296 -0
- package/mcp/index.ts +2 -0
- package/package.json +20 -8
- package/page-extensions/GlobalComponents.ts +30 -0
- package/page-extensions/GoToDeepLink.ts +9 -0
- package/page-extensions/LoginFeatures.ts +8 -0
- package/page-extensions/SubjectRegistry.ts +32 -0
- package/page-extensions/UserSimulation.ts +21 -0
- package/page-extensions/WaitEventHandler.ts +20 -0
- package/page-overrides/ClickOverride.ts +36 -55
- package/page-overrides/FillOverride.ts +59 -73
- package/promptCredentials.js +1 -1
- package/scripts/Testwise.template.json +1 -1
- package/scripts/diagram.js +2267 -0
- package/scripts/main.js +84 -63
- package/scripts/postinstall.js +55 -42
- package/scripts/setup.js +91 -37
- package/scripts/sync.js +767 -748
- package/services/ConfigBuilder.ts +24 -0
- package/services/IndiciumApi.service.ts +44 -6
- package/services/Logger.ts +40 -0
- package/templates/copilot-instructions.md +130 -0
- package/templates/mcp.json +9 -0
- package/templates/testwise-test-expert.agent.md +453 -0
- package/tests/tsconfig.json +12 -0
- package/tsconfig.json +6 -2
- package/types/Components.ts +17 -2
- package/types/LocatorType.ts +5 -0
- package/types/PollTypes.ts +8 -0
- package/types/Test.ts +18 -0
- package/types/Universal.ts +12 -0
- package/types/index.ts +2 -0
- package/dist/interfaces/IStoredTestResults.d.ts +0 -5
- package/dist/interfaces/IStoredTestResults.js +0 -2
- package/dist/interfaces/IStoredTestResults.js.map +0 -1
- package/dist/templates/test-artifacts/SubjectPageBase.d.ts +0 -5
- package/dist/templates/test-artifacts/SubjectPageBase.js +0 -6
- package/dist/templates/test-artifacts/SubjectPageBase.js.map +0 -1
- package/dist/templates/test-artifacts/screens/index.d.ts +0 -1
- package/dist/templates/test-artifacts/screens/index.js +0 -2
- package/dist/templates/test-artifacts/screens/index.js.map +0 -1
- package/dist/templates/test-artifacts/subjects/index.d.ts +0 -1
- package/dist/templates/test-artifacts/subjects/index.js +0 -2
- package/dist/templates/test-artifacts/subjects/index.js.map +0 -1
- package/interfaces/IStoredTestResults.ts +0 -6
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { IndentationText, Project, QuoteKind, Scope, type SourceFile, StructureKind } from 'ts-morph';
|
|
2
|
+
import type { SubjectComponents } from '../types/Components.js';
|
|
3
|
+
import type { ComponentClassModel, TsFileModel } from './TsFileModel.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Converts in-memory TypeScript file models (`TsFileModel`, `ComponentClassModel`)
|
|
7
|
+
* into formatted TypeScript source strings using `ts-morph` AST manipulation.
|
|
8
|
+
*
|
|
9
|
+
* **Why ts-morph instead of string templates:** String-template code generation
|
|
10
|
+
* is fragile — it breaks on quoting, indentation, and special characters.
|
|
11
|
+
* `ts-morph` builds a real AST and prints it, so the output is always
|
|
12
|
+
* syntactically valid and consistently formatted.
|
|
13
|
+
*
|
|
14
|
+
* **Exported functions:**
|
|
15
|
+
* - `serializeTsFile(model)` — writes a complete subject class file from a
|
|
16
|
+
* `TsFileModel` (used by `SubjectGenerator`).
|
|
17
|
+
* - `appendComponentClass(existingContent, model)` — appends a typed component
|
|
18
|
+
* class body to an existing interface file (used by `SubjectComponentGenerator`).
|
|
19
|
+
* - `refineComponentInterface(rawContent, componentType)` — post-processes a
|
|
20
|
+
* raw quicktype interface file (adds Testwise imports, removes `Locator` base).
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
function createProject(existingContent?: string): { project: Project; file: SourceFile } {
|
|
24
|
+
const project = new Project({
|
|
25
|
+
useInMemoryFileSystem: true,
|
|
26
|
+
skipAddingFilesFromTsConfig: true,
|
|
27
|
+
manipulationSettings: {
|
|
28
|
+
indentationText: IndentationText.TwoSpaces,
|
|
29
|
+
quoteKind: QuoteKind.Single
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
const file = project.createSourceFile('output.ts', existingContent ?? '');
|
|
33
|
+
return { project, file };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Builds a subject class file from a typed model. No string templates. */
|
|
37
|
+
export function serializeTsFile(model: TsFileModel): string {
|
|
38
|
+
const { file } = createProject();
|
|
39
|
+
|
|
40
|
+
for (const imp of model.imports) {
|
|
41
|
+
file.addImportDeclaration({
|
|
42
|
+
isTypeOnly: imp.isTypeOnly,
|
|
43
|
+
namedImports: imp.namedImports.map((n) => ({ name: n.name, isTypeOnly: n.isTypeOnly ?? false })),
|
|
44
|
+
moduleSpecifier: imp.from
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const cls = model.classModel;
|
|
49
|
+
|
|
50
|
+
file.addClass({
|
|
51
|
+
name: cls.name,
|
|
52
|
+
extends: cls.extendsClass,
|
|
53
|
+
implements: [cls.implementsInterface],
|
|
54
|
+
isExported: true,
|
|
55
|
+
properties: cls.properties.map((p) => ({
|
|
56
|
+
kind: StructureKind.Property as const,
|
|
57
|
+
scope: p.access === 'private' ? Scope.Private : undefined,
|
|
58
|
+
name: p.name,
|
|
59
|
+
type: p.type
|
|
60
|
+
})),
|
|
61
|
+
ctors: [
|
|
62
|
+
{
|
|
63
|
+
parameters: cls.constructor.params.map((p) => ({ name: p.name, type: p.type })),
|
|
64
|
+
statements: [
|
|
65
|
+
`super(${cls.constructor.superCall});`,
|
|
66
|
+
...cls.constructor.assignments.map((a) => `this.${a.property} = ${a.value};`),
|
|
67
|
+
...cls.constructor.extraLines
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
methods: (cls.methods ?? []).map((m) => ({
|
|
72
|
+
scope: Scope.Public,
|
|
73
|
+
isAsync: m.isAsync,
|
|
74
|
+
name: m.name,
|
|
75
|
+
statements: m.bodyLines
|
|
76
|
+
}))
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
return file.print();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Parses an existing component interface file, appends the component class and
|
|
84
|
+
* any required control imports, and returns the complete printed file.
|
|
85
|
+
* Replaces string-template-based class body generation — no string templates.
|
|
86
|
+
*/
|
|
87
|
+
export function appendComponentClass(existingContent: string, model: ComponentClassModel): string {
|
|
88
|
+
const { file } = createProject(existingContent);
|
|
89
|
+
|
|
90
|
+
addControlImports(file, model);
|
|
91
|
+
|
|
92
|
+
const contextProp = {
|
|
93
|
+
kind: StructureKind.Property as const,
|
|
94
|
+
scope: Scope.Private,
|
|
95
|
+
name: '_context',
|
|
96
|
+
type: 'Locator'
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
if (model.componentType === 'Grid') {
|
|
100
|
+
file.addClass({
|
|
101
|
+
name: `${model.interfaceName}Component`,
|
|
102
|
+
extends: model.componentType,
|
|
103
|
+
implements: [model.interfaceName],
|
|
104
|
+
isExported: true,
|
|
105
|
+
properties: [contextProp],
|
|
106
|
+
ctors: [
|
|
107
|
+
{
|
|
108
|
+
parameters: [{ name: 'context', type: 'Locator' }],
|
|
109
|
+
statements: ['super(context);', 'this._context = context;']
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
getAccessors: model.getters.map((g) => ({
|
|
113
|
+
scope: Scope.Public,
|
|
114
|
+
name: g.name,
|
|
115
|
+
returnType: g.returnType,
|
|
116
|
+
statements: [g.bodyLine]
|
|
117
|
+
}))
|
|
118
|
+
});
|
|
119
|
+
} else {
|
|
120
|
+
file.addClass({
|
|
121
|
+
name: `${model.interfaceName}Component`,
|
|
122
|
+
extends: model.componentType,
|
|
123
|
+
implements: [model.interfaceName],
|
|
124
|
+
isExported: true,
|
|
125
|
+
properties: [contextProp, ...model.properties.map((p) => ({ name: p.name, type: p.type }))],
|
|
126
|
+
ctors: [
|
|
127
|
+
{
|
|
128
|
+
parameters: [{ name: 'context', type: 'Locator' }],
|
|
129
|
+
statements: [
|
|
130
|
+
'super(context);',
|
|
131
|
+
'this._context = context;',
|
|
132
|
+
...model.assignments.map((a) => `this.${a.property} = ${a.value};`)
|
|
133
|
+
]
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return file.print();
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// ── Control import resolution ──────────────────────────────────────────────
|
|
143
|
+
|
|
144
|
+
const controlImportMap: Record<string, { createFn: string; moduleSpecifier: string }> = {
|
|
145
|
+
ILookupDropdown: {
|
|
146
|
+
createFn: 'createLookupDropdown',
|
|
147
|
+
moduleSpecifier: '../../../../controls/LookupDropdown.js'
|
|
148
|
+
},
|
|
149
|
+
IFormComboBox: {
|
|
150
|
+
createFn: 'createFormComboBox',
|
|
151
|
+
moduleSpecifier: '../../../../controls/FormComboBox.js'
|
|
152
|
+
},
|
|
153
|
+
IInputFieldControl: {
|
|
154
|
+
createFn: 'createInputFieldControl',
|
|
155
|
+
moduleSpecifier: '../../../../controls/InputFieldControl.js'
|
|
156
|
+
},
|
|
157
|
+
IDateControl: {
|
|
158
|
+
createFn: 'createDateControl',
|
|
159
|
+
moduleSpecifier: '../../../../controls/DateControl.js'
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
function addControlImports(file: SourceFile, model: ComponentClassModel): void {
|
|
164
|
+
const usedTypes = new Set(model.properties.map((p) => p.type));
|
|
165
|
+
|
|
166
|
+
for (const [typeName, { createFn, moduleSpecifier }] of Object.entries(controlImportMap)) {
|
|
167
|
+
if (!usedTypes.has(typeName)) continue;
|
|
168
|
+
|
|
169
|
+
const alreadyImported = file.getImportDeclarations().some((d) => d.getModuleSpecifierValue() === moduleSpecifier);
|
|
170
|
+
if (alreadyImported) continue;
|
|
171
|
+
|
|
172
|
+
file.addImportDeclaration({
|
|
173
|
+
namedImports: [{ name: createFn }, { name: typeName, isTypeOnly: true }],
|
|
174
|
+
moduleSpecifier
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// ── Form property-type suffix mapping ─────────────────────────────────────
|
|
180
|
+
|
|
181
|
+
const formTypeSuffixMap: Record<string, string> = {
|
|
182
|
+
Lookup: 'ILookupDropdown',
|
|
183
|
+
ComboBox: 'IFormComboBox',
|
|
184
|
+
Field: 'IInputFieldControl',
|
|
185
|
+
DatePicker: 'IDateControl'
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Transforms a raw quicktype-generated interface file into a refined component
|
|
190
|
+
* interface file using ts-morph AST manipulation — no string templates.
|
|
191
|
+
*
|
|
192
|
+
* Replaces the five string-manipulation methods previously in SubjectComponentGenerator:
|
|
193
|
+
* removeLocatorInterface, addComponentImports, setSubjectExtendsComponent,
|
|
194
|
+
* transformGridInterface, transformInterfaceTypes.
|
|
195
|
+
*/
|
|
196
|
+
export function refineComponentInterface(rawContent: string, componentType: SubjectComponents): string {
|
|
197
|
+
const { file } = createProject(rawContent);
|
|
198
|
+
|
|
199
|
+
// Remove the stray Locator interface that quicktype emits alongside the real schema
|
|
200
|
+
file.getInterface('Locator')?.remove();
|
|
201
|
+
|
|
202
|
+
// Prepend the imports this component type needs
|
|
203
|
+
file.insertImportDeclarations(0, [
|
|
204
|
+
{
|
|
205
|
+
namedImports: [{ name: componentType }],
|
|
206
|
+
moduleSpecifier: '../../../../components/index.js'
|
|
207
|
+
},
|
|
208
|
+
...(componentType === 'Grid'
|
|
209
|
+
? [
|
|
210
|
+
{
|
|
211
|
+
namedImports: [{ name: 'createGridColumnControl' }, { name: 'IGridColumnControl', isTypeOnly: true }],
|
|
212
|
+
moduleSpecifier: '../../../../controls/GridColumnControl.js'
|
|
213
|
+
}
|
|
214
|
+
]
|
|
215
|
+
: []),
|
|
216
|
+
{
|
|
217
|
+
isTypeOnly: true,
|
|
218
|
+
namedImports: [{ name: 'Locator' }],
|
|
219
|
+
moduleSpecifier: '@playwright/test'
|
|
220
|
+
}
|
|
221
|
+
]);
|
|
222
|
+
|
|
223
|
+
// Find the main interface (no extends clause yet) and make it extend the component
|
|
224
|
+
const mainInterface = file.getInterfaces().find((i) => i.getExtends().length === 0);
|
|
225
|
+
if (mainInterface) {
|
|
226
|
+
mainInterface.addExtends(componentType);
|
|
227
|
+
|
|
228
|
+
if (componentType === 'Grid') {
|
|
229
|
+
// Swap every Locator-typed property for a readonly IGridColumnControl
|
|
230
|
+
for (const prop of mainInterface.getProperties()) {
|
|
231
|
+
const typeText = prop.getTypeNode()?.getText() ?? '';
|
|
232
|
+
if (typeText === 'Locator' || typeText === 'Locator[]') {
|
|
233
|
+
prop.setIsReadonly(true);
|
|
234
|
+
prop.setType('IGridColumnControl');
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
} else {
|
|
238
|
+
// Map Form property name suffixes to their control types
|
|
239
|
+
for (const prop of mainInterface.getProperties()) {
|
|
240
|
+
const suffix = Object.keys(formTypeSuffixMap).find((s) => prop.getName().endsWith(s));
|
|
241
|
+
if (suffix) prop.setType(formTypeSuffixMap[suffix]);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return file.print();
|
|
247
|
+
}
|
|
@@ -1,67 +1,104 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
|
-
import * as path from 'node:path';
|
|
3
|
-
import { PathResolver } from '../../helpers/PathResolver.js';
|
|
4
2
|
import type { IRegisteredSubjects } from '../../interfaces/IRegisteredSubjects.js';
|
|
5
3
|
import type { ISubject } from '../../interfaces/ISubject.js';
|
|
4
|
+
import { PipelinePaths } from './PipelinePaths.js';
|
|
6
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Thin file-system accessor that reads all JSON seed-data files used by the
|
|
8
|
+
* artifact-builder pipeline and returns them as typed objects.
|
|
9
|
+
*
|
|
10
|
+
* **What it does:** Abstracts away all `fs.readFileSync` / JSON.parse calls so
|
|
11
|
+
* that pipeline steps only deal with typed data, never raw file I/O. All path
|
|
12
|
+
* resolution is delegated to `PipelinePaths` — there are no hardcoded paths here.
|
|
13
|
+
*
|
|
14
|
+
* **Why it exists as a separate class:** Injecting `DataRetriever` into each
|
|
15
|
+
* pipeline step makes the steps unit-testable without touching the real
|
|
16
|
+
* filesystem. Tests pass a `DataRetriever` constructed with a fake
|
|
17
|
+
* `PipelinePaths` that points to a temp directory.
|
|
18
|
+
*
|
|
19
|
+
* **For contributors:** If the pipeline gains a new seed-data file, add a
|
|
20
|
+
* typed accessor method here (and a corresponding path getter to
|
|
21
|
+
* `PipelinePaths`).
|
|
22
|
+
*/
|
|
7
23
|
export class DataRetriever {
|
|
8
|
-
private
|
|
24
|
+
private readonly _paths: PipelinePaths;
|
|
25
|
+
|
|
26
|
+
constructor(paths?: PipelinePaths) {
|
|
27
|
+
/* v8 ignore next -- default only used at runtime, not in unit tests */
|
|
28
|
+
this._paths = paths ?? new PipelinePaths();
|
|
29
|
+
}
|
|
9
30
|
|
|
10
31
|
public getSubjectsSeedData(): ISubject[] {
|
|
11
|
-
const seedPath =
|
|
32
|
+
const seedPath = this._paths.subjectsJson;
|
|
33
|
+
|
|
12
34
|
if (!fs.existsSync(seedPath)) {
|
|
13
|
-
|
|
35
|
+
throw new Error(`subjects.json not found at: ${seedPath}. Run the model data build step first.`);
|
|
14
36
|
}
|
|
15
37
|
|
|
16
|
-
|
|
17
|
-
return this.toISubject(json) as unknown as ISubject[];
|
|
38
|
+
return this.parseJsonFile<ISubject[]>(seedPath);
|
|
18
39
|
}
|
|
19
40
|
|
|
20
41
|
public getRegisteredSubjects(): IRegisteredSubjects[] | null {
|
|
21
|
-
const registeredSubjectsPath =
|
|
42
|
+
const registeredSubjectsPath = this._paths.registeredSubjectsJson;
|
|
22
43
|
|
|
23
44
|
if (!fs.existsSync(registeredSubjectsPath)) {
|
|
24
|
-
console.info(`
|
|
25
|
-
|
|
45
|
+
console.info(`registeredSubjects.json not found at: ${registeredSubjectsPath}. No subjects are registered.`);
|
|
26
46
|
return null;
|
|
27
47
|
}
|
|
28
48
|
|
|
29
|
-
|
|
30
|
-
return this.toIRegisteredSubjects(json) as unknown as IRegisteredSubjects[];
|
|
49
|
+
return this.parseJsonFile<IRegisteredSubjects[]>(registeredSubjectsPath);
|
|
31
50
|
}
|
|
32
51
|
|
|
33
52
|
public getSubjectsToBuild(): ISubject[] {
|
|
34
|
-
const subjectsToBuildPath =
|
|
35
|
-
if (!fs.existsSync(subjectsToBuildPath)) {
|
|
36
|
-
console.info(`subjectsToBuild.json not found at: ${subjectsToBuildPath}. Using all subjects as fallback.`);
|
|
53
|
+
const subjectsToBuildPath = this._paths.subjectsToBuildJson;
|
|
37
54
|
|
|
55
|
+
if (!fs.existsSync(subjectsToBuildPath)) {
|
|
56
|
+
console.info(`subjectsToBuild.json not found – falling back to full subjects seed data.`);
|
|
38
57
|
return this.getSubjectsSeedData();
|
|
39
58
|
}
|
|
40
59
|
|
|
41
|
-
|
|
42
|
-
return this.toISubject(json) as unknown as ISubject[];
|
|
60
|
+
return this.parseJsonFile<ISubject[]>(subjectsToBuildPath);
|
|
43
61
|
}
|
|
44
62
|
|
|
45
63
|
public getScreensToBuild(): string[] {
|
|
46
|
-
const screensToBuildPath =
|
|
64
|
+
const screensToBuildPath = this._paths.screensToBuildJson;
|
|
65
|
+
|
|
47
66
|
if (!fs.existsSync(screensToBuildPath)) {
|
|
48
|
-
console.info(`screensToBuild.json not found.`);
|
|
67
|
+
console.info(`screensToBuild.json not found – all screens will be processed.`);
|
|
49
68
|
return [];
|
|
50
69
|
}
|
|
51
70
|
|
|
52
|
-
|
|
53
|
-
return JSON.parse(json) as string[];
|
|
71
|
+
return this.parseJsonFile<string[]>(screensToBuildPath);
|
|
54
72
|
}
|
|
55
73
|
|
|
56
|
-
public
|
|
57
|
-
|
|
74
|
+
public getScreenComponentMeta(screenTypeId: string): Record<string, string> {
|
|
75
|
+
const schemaPath = `${this._paths.screenSchemas}/${screenTypeId}.json`;
|
|
76
|
+
|
|
77
|
+
if (!fs.existsSync(schemaPath)) return {};
|
|
78
|
+
|
|
79
|
+
const schema = this.parseJsonFile<{ properties?: Record<string, unknown> }>(schemaPath);
|
|
80
|
+
const result: Record<string, string> = {};
|
|
81
|
+
|
|
82
|
+
for (const originalId of Object.keys(schema.properties ?? {})) {
|
|
83
|
+
// Normalize to lowercase-alphanumeric so the lookup is insensitive to
|
|
84
|
+
// camelCase variations between change-case and quicktype's nice-property-names.
|
|
85
|
+
const normalizedKey = originalId.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
86
|
+
result[normalizedKey] = originalId;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return result;
|
|
58
90
|
}
|
|
59
91
|
|
|
60
|
-
|
|
61
|
-
return
|
|
92
|
+
public getSeedDataDirectory(): string {
|
|
93
|
+
return this._paths.seedData;
|
|
62
94
|
}
|
|
63
95
|
|
|
64
|
-
private
|
|
65
|
-
|
|
96
|
+
private parseJsonFile<T>(filePath: string): T {
|
|
97
|
+
const raw = fs.readFileSync(filePath, 'utf-8');
|
|
98
|
+
try {
|
|
99
|
+
return JSON.parse(raw) as T;
|
|
100
|
+
} catch (cause) {
|
|
101
|
+
throw new Error(`Failed to parse JSON at ${filePath}: ${(cause as Error).message}`);
|
|
102
|
+
}
|
|
66
103
|
}
|
|
67
104
|
}
|
|
@@ -1,8 +1,24 @@
|
|
|
1
1
|
import * as path from 'node:path';
|
|
2
2
|
import { pascalCase, snakeCase } from 'change-case';
|
|
3
3
|
import { KnownElementTypes } from '../../enums/ElementTypes.js';
|
|
4
|
-
import type {
|
|
5
|
-
|
|
4
|
+
import type { SubjectComponents } from '../../types/Components.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Centralises all naming and string-transformation logic used by the
|
|
8
|
+
* artifact-builder pipeline.
|
|
9
|
+
*
|
|
10
|
+
* **What it does:**
|
|
11
|
+
* - Converts subject/variant/screentype tuples into the correct PascalCase
|
|
12
|
+
* class names that are written to the generated subject files.
|
|
13
|
+
* - Maps `control_type` strings from the Indicium API to the Testwise control
|
|
14
|
+
* class suffix that appears in generated component interfaces
|
|
15
|
+
* (e.g. `"lookup"` → `"Lookup"` → property name ends in `Lookup`).
|
|
16
|
+
* - Handles edge cases like `Form` vs `Grid` defaults and multi-variant naming.
|
|
17
|
+
*
|
|
18
|
+
* **For contributors:** If the Thinkwise model introduces a new control type
|
|
19
|
+
* that should map to a different Testwise control, add it to the mapping
|
|
20
|
+
* matrix inside `getElementSuffixFromControlTypeAndComponentType`.
|
|
21
|
+
*/
|
|
6
22
|
export class NamingHandler {
|
|
7
23
|
public getDefaultElementSuffixFromComponentType(componentType: SubjectComponents): KnownElementTypes {
|
|
8
24
|
const controlTypeMapping: Record<SubjectComponents, KnownElementTypes> = {
|
|
@@ -47,49 +63,6 @@ export class NamingHandler {
|
|
|
47
63
|
).toLowerCase();
|
|
48
64
|
}
|
|
49
65
|
|
|
50
|
-
public getIdFromElementName(elementName: string, componentType: SubjectComponents, controlType: string): string {
|
|
51
|
-
const elementSuffixToRemove = this.getElementSuffixFromControlTypeAndComponentType(controlType, componentType);
|
|
52
|
-
const elementSuffixToRemoveFormatted = elementSuffixToRemove.replace(/_/g, '-').toLowerCase();
|
|
53
|
-
|
|
54
|
-
let id = this.toSnakeCase(elementName)
|
|
55
|
-
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
56
|
-
.toLowerCase()
|
|
57
|
-
.replace(/_/g, '-');
|
|
58
|
-
|
|
59
|
-
if (elementSuffixToRemove) {
|
|
60
|
-
const suffixRegex = new RegExp(`-?${elementSuffixToRemoveFormatted}$`, 'i');
|
|
61
|
-
id = id.replace(suffixRegex, '');
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return id.replace(/-+/g, '-').replace(/-+$/g, '');
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
public getComponentTypeFromFileName(fileName: string): SubjectComponents {
|
|
68
|
-
// ToDo: use this
|
|
69
|
-
const match = fileName.match(/([A-Z][a-z]+)(?=\.ts$)/);
|
|
70
|
-
if (match) {
|
|
71
|
-
const componentName = match[1];
|
|
72
|
-
if (componentName === 'Form') return 'Form';
|
|
73
|
-
if (componentName === 'Grid') return 'Grid';
|
|
74
|
-
}
|
|
75
|
-
throw new Error(`Unknown component type in file name: ${fileName}`);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
public getElementTypeFromElementName(elementName: string): string {
|
|
79
|
-
const snakeCaseElementName = this.toSnakeCase(elementName);
|
|
80
|
-
const parts = snakeCaseElementName.split('_');
|
|
81
|
-
|
|
82
|
-
for (let i = parts.length - 1; i > 0; i--) {
|
|
83
|
-
const candidate = parts.slice(i).join('_');
|
|
84
|
-
|
|
85
|
-
if (Object.values(KnownElementTypes).includes(candidate as KnownElementTypes)) {
|
|
86
|
-
return candidate;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
throw new Error(`No KnownElementType match found for a partial suffix of "${elementName}"`);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
66
|
public getSubjectFromFileName(fileName: string): string {
|
|
94
67
|
return fileName.replace(/([A-Z][a-z0-9]*)$/, '');
|
|
95
68
|
}
|
|
@@ -102,6 +75,10 @@ export class NamingHandler {
|
|
|
102
75
|
return pascalCase(name);
|
|
103
76
|
}
|
|
104
77
|
|
|
78
|
+
public toSubjectPascalCase(name: string): string {
|
|
79
|
+
return this.toPascalCase(name.replace(/_(\d)/g, '$1'));
|
|
80
|
+
}
|
|
81
|
+
|
|
105
82
|
public formatPropertyName(name: string): string {
|
|
106
83
|
return name.charAt(0).toLowerCase() + name.slice(1);
|
|
107
84
|
}
|
|
@@ -114,45 +91,13 @@ export class NamingHandler {
|
|
|
114
91
|
return snakeCase(value);
|
|
115
92
|
}
|
|
116
93
|
|
|
117
|
-
public getComponentIdFromName(componentName: string, componentType: ScreenComponents): string {
|
|
118
|
-
if (componentType === 'ActionBar' || componentType === 'CustomActionBar') {
|
|
119
|
-
const capitalizedComponentName = this.capitalizeFirstLetter(componentName);
|
|
120
|
-
return capitalizedComponentName.replace(/Toolbar/, 'Toolbar_');
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (componentType === 'Splitter') {
|
|
124
|
-
const componentId = componentName.toLowerCase();
|
|
125
|
-
|
|
126
|
-
if (/^splitter\d+$/.test(componentId)) {
|
|
127
|
-
return componentId;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return componentId.replace(/splitter/, 'splitter-');
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if (componentType === 'Tab') {
|
|
134
|
-
return this.capitalizeFirstLetter(componentName);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
return componentName;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
94
|
public capitalizeFirstLetter(value: string): string {
|
|
141
95
|
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
142
96
|
}
|
|
143
97
|
|
|
144
|
-
public getTabParentFromComponentName(componentName: string): string {
|
|
145
|
-
const match = componentName.match(/^[a-z0-9]+(?=[A-Z])/);
|
|
146
|
-
if (match) {
|
|
147
|
-
return match[0];
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
throw new Error(`Could not extract tab parent from component name: ${componentName}`);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
98
|
public generateSubjectClassName(subject: { subject: string; screentype_context: string; variant: string }): string {
|
|
154
99
|
const uniqueSubjectIdentifier = subject.variant !== '' ? `${subject.subject}_${subject.variant}` : subject.subject;
|
|
155
100
|
const className = `${uniqueSubjectIdentifier}_${subject.screentype_context}`;
|
|
156
|
-
return this.
|
|
101
|
+
return this.toSubjectPascalCase(className);
|
|
157
102
|
}
|
|
158
103
|
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import * as path from 'node:path';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { PathResolver } from '../../helpers/PathResolver.js';
|
|
5
|
+
|
|
6
|
+
// Resolved once at module load so every PipelinePaths instance shares
|
|
7
|
+
// the same package root without re-computing it on construction.
|
|
8
|
+
const _moduleFilename = fileURLToPath(import.meta.url);
|
|
9
|
+
const _moduleDirname = dirname(_moduleFilename);
|
|
10
|
+
|
|
11
|
+
// dist/artifact-builder/helpers → dist/artifact-builder → dist → package-root
|
|
12
|
+
const packageRoot = path.resolve(_moduleDirname, '../../..');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Single source of truth for all filesystem paths used by the artifact-builder
|
|
16
|
+
* pipeline.
|
|
17
|
+
*
|
|
18
|
+
* - Generated seed data (subjects.json, screen-schemas) lives under the
|
|
19
|
+
* **package root** (`node_modules/@thinkwise/testwise/seed-data/`) because
|
|
20
|
+
* it is rebuilt on every sync and can safely be regenerated.
|
|
21
|
+
* - `registeredSubjects.json` lives in the **consumer project root** because
|
|
22
|
+
* it represents the user's curated subject list and must never be lost when
|
|
23
|
+
* `node_modules` is wiped and reinstalled.
|
|
24
|
+
*/
|
|
25
|
+
export class PipelinePaths {
|
|
26
|
+
private readonly _packageRoot: string;
|
|
27
|
+
private readonly _consumerRoot: string;
|
|
28
|
+
|
|
29
|
+
constructor() {
|
|
30
|
+
this._packageRoot = packageRoot;
|
|
31
|
+
/* v8 ignore next -- PathResolver walks the real filesystem; exercised via integration */
|
|
32
|
+
this._consumerRoot = new PathResolver().getConsumerRootDirectory();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// ── Package root – seed data ─────────────────────────────────────────────
|
|
36
|
+
|
|
37
|
+
/** `<package>/seed-data/` */
|
|
38
|
+
get seedData(): string {
|
|
39
|
+
return path.join(this._packageRoot, 'seed-data');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** `<consumer>/seed-data/screen-schemas/` */
|
|
43
|
+
get screenSchemas(): string {
|
|
44
|
+
return path.join(this.seedData, 'screen-schemas');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** `<consumer>/seed-data/subjects.json` */
|
|
48
|
+
get subjectsJson(): string {
|
|
49
|
+
return path.join(this.seedData, 'subjects.json');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** `<consumer>/seed-data/subjectsToBuild.json` */
|
|
53
|
+
get subjectsToBuildJson(): string {
|
|
54
|
+
return path.join(this.seedData, 'subjectsToBuild.json');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** `<consumer>/seed-data/screensToBuild.json` */
|
|
58
|
+
get screensToBuildJson(): string {
|
|
59
|
+
return path.join(this.seedData, 'screensToBuild.json');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** `<consumer>/seed-data/registeredSubjects.json` – lives in the consumer project so it survives `npm install` */
|
|
63
|
+
get registeredSubjectsJson(): string {
|
|
64
|
+
return path.join(this._consumerRoot, 'seed-data', 'registeredSubjects.json');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ── Package root – generated artifacts ─────────────────────────────────
|
|
68
|
+
|
|
69
|
+
/** `<package>/test-artifacts/` */
|
|
70
|
+
get testArtifacts(): string {
|
|
71
|
+
return path.join(this._packageRoot, 'test-artifacts');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** `<package>/test-artifacts/screens/` */
|
|
75
|
+
get screens(): string {
|
|
76
|
+
return path.join(this.testArtifacts, 'screens');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** `<package>/test-artifacts/screens/index.ts` */
|
|
80
|
+
get screensIndex(): string {
|
|
81
|
+
return path.join(this.screens, 'index.ts');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** `<package>/test-artifacts/subjects/` */
|
|
85
|
+
get subjects(): string {
|
|
86
|
+
return path.join(this.testArtifacts, 'subjects');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* `<package>/dist/test-artifacts/schemas/`
|
|
91
|
+
*
|
|
92
|
+
* Intermediate JSON schemas are kept inside `dist/` so that the TypeScript
|
|
93
|
+
* compiler does not include them in compilation but they are accessible at
|
|
94
|
+
* runtime after the initial `tsc` pass.
|
|
95
|
+
*/
|
|
96
|
+
get schemas(): string {
|
|
97
|
+
return path.join(this._packageRoot, 'dist', 'test-artifacts', 'schemas');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ── Package root – source files ─────────────────────────────────────────
|
|
101
|
+
|
|
102
|
+
/** `<package>/page-extensions/SubjectRegistry.ts` */
|
|
103
|
+
get subjectRegistry(): string {
|
|
104
|
+
return path.join(this._packageRoot, 'page-extensions', 'SubjectRegistry.ts');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** `<package>/templates/SubjectRegistry.template.ts` */
|
|
108
|
+
get subjectRegistryTemplate(): string {
|
|
109
|
+
return path.join(this._packageRoot, 'templates', 'SubjectRegistry.template.ts');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// ── Derived helpers ─────────────────────────────────────────────────────
|
|
113
|
+
|
|
114
|
+
/** `<package>/test-artifacts/subjects/<subjectName>/` */
|
|
115
|
+
subjectFolder(subjectName: string): string {
|
|
116
|
+
return path.join(this.subjects, subjectName);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** `<package>/test-artifacts/subjects/<subjectName>/Components/` */
|
|
120
|
+
subjectComponentsFolder(subjectName: string): string {
|
|
121
|
+
return path.join(this.subjectFolder(subjectName), 'Components');
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { performance } from 'node:perf_hooks';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Minimal lap timer used to log how long each pipeline step takes.
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* const sw = new Stopwatch();
|
|
8
|
+
* const lap = sw.start('SchemaGenerator');
|
|
9
|
+
* // ... do work ...
|
|
10
|
+
* lap.stop(); // logs: "[0.412s]: SchemaGenerator"
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
3
13
|
export class Stopwatch {
|
|
4
14
|
start(message: string) {
|
|
5
15
|
const startTime = performance.now();
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
export * from './ArtifactManager.js';
|
|
2
|
+
export * from './ComponentClassModelBuilder.js';
|
|
2
3
|
export * from './helpers/index.js';
|
|
3
4
|
export * from './InterfaceGenerator.js';
|
|
4
5
|
export * from './ModelDataRefiner.js';
|
|
5
6
|
export * from './SchemaGenerator.js';
|
|
6
7
|
export * from './ScreenInterfaceRefiner.js';
|
|
8
|
+
export * from './SubjectClassModelBuilder.js';
|
|
7
9
|
export * from './SubjectComponentGenerator.js';
|
|
8
10
|
export * from './SubjectGenerator.js';
|
|
9
11
|
export * from './SubjectRegistration.js';
|
|
12
|
+
export * from './TsFileModel.js';
|
|
13
|
+
export * from './TsFileSerializer.js';
|