@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
|
@@ -1,32 +1,46 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
|
-
import { dirname } from 'node:path';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
|
-
import { DataRetriever, NamingHandler } from '../index.js';
|
|
6
3
|
import type { ISubject } from '../interfaces/ISubject.js';
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
} from '
|
|
13
|
-
|
|
14
|
-
|
|
4
|
+
import type { ScreenComponents } from '../types/Components.js';
|
|
5
|
+
import type { LocatorType } from '../types/LocatorType.js';
|
|
6
|
+
import { DataRetriever, NamingHandler, PipelinePaths } from './helpers/index.js';
|
|
7
|
+
import { SelectorBuilder } from './SelectorBuilder.js';
|
|
8
|
+
import { type ComponentEntry, SubjectClassModelBuilder } from './SubjectClassModelBuilder.js';
|
|
9
|
+
import { serializeTsFile } from './TsFileSerializer.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* **Pipeline Step 6** — Generates typed TypeScript subject class files under
|
|
13
|
+
* `test-artifacts/subjects/<SubjectName>/`.
|
|
14
|
+
*
|
|
15
|
+
* **What it does:**
|
|
16
|
+
* - Reads `seed-data/subjectsToBuild.json` to get the list of subjects to
|
|
17
|
+
* generate.
|
|
18
|
+
* - For each subject, uses `SubjectClassModelBuilder` to produce an in-memory
|
|
19
|
+
* model of the class, then hands it to `TsFileSerializer` to write the
|
|
20
|
+
* TypeScript file to disk.
|
|
21
|
+
* - Each generated class extends `SubjectPageBase`, imports the matching
|
|
22
|
+
* screen interface, and declares typed component properties.
|
|
23
|
+
* - After generating all class files, writes an `index.ts` barrel file for
|
|
24
|
+
* each subject folder.
|
|
25
|
+
*
|
|
26
|
+
* **When it runs:** Step 6 of `testwise sync`, after `SubjectComponentGenerator`
|
|
27
|
+
* has written the component interface files.
|
|
28
|
+
*/
|
|
15
29
|
export class SubjectGenerator {
|
|
16
|
-
private static readonly SUBJECTS_RELATIVE_PATH = 'test-artifacts/subjects';
|
|
17
|
-
|
|
18
|
-
private readonly _currentFilename: string;
|
|
19
|
-
private readonly _currentDirname: string;
|
|
20
30
|
private readonly _subjectsDirectory: string;
|
|
31
|
+
private readonly _screensDirectory: string;
|
|
21
32
|
private readonly _namingHandler: NamingHandler;
|
|
22
33
|
private readonly _selectorBuilder: SelectorBuilder;
|
|
34
|
+
private readonly _paths: PipelinePaths;
|
|
35
|
+
private readonly _modelBuilder: SubjectClassModelBuilder;
|
|
23
36
|
|
|
24
|
-
constructor() {
|
|
25
|
-
this.
|
|
26
|
-
this.
|
|
27
|
-
this.
|
|
37
|
+
constructor(paths?: PipelinePaths) {
|
|
38
|
+
this._paths = paths ?? new PipelinePaths();
|
|
39
|
+
this._subjectsDirectory = this._paths.subjects;
|
|
40
|
+
this._screensDirectory = this._paths.screens;
|
|
28
41
|
this._namingHandler = new NamingHandler();
|
|
29
42
|
this._selectorBuilder = new SelectorBuilder();
|
|
43
|
+
this._modelBuilder = new SubjectClassModelBuilder(this._namingHandler, this._selectorBuilder);
|
|
30
44
|
}
|
|
31
45
|
|
|
32
46
|
public run(): void {
|
|
@@ -35,7 +49,7 @@ export class SubjectGenerator {
|
|
|
35
49
|
}
|
|
36
50
|
|
|
37
51
|
private generateSubjectClasses(): void {
|
|
38
|
-
const subjects: ISubject[] = new DataRetriever().getSubjectsToBuild();
|
|
52
|
+
const subjects: ISubject[] = new DataRetriever(this._paths).getSubjectsToBuild();
|
|
39
53
|
|
|
40
54
|
subjects.forEach((subject) => {
|
|
41
55
|
this.createSubjectClass(subject);
|
|
@@ -78,38 +92,21 @@ export class SubjectGenerator {
|
|
|
78
92
|
const screenInterfaceName = this._namingHandler.generateScreenInterfaceName(subject.screentype_id);
|
|
79
93
|
const screenInterfacePath = this.getScreenInterfacePath(screenInterfaceName);
|
|
80
94
|
const screenFileContent = fs.readFileSync(screenInterfacePath, 'utf-8');
|
|
81
|
-
const subjectFolderName = this._namingHandler.
|
|
95
|
+
const subjectFolderName = this._namingHandler.toSubjectPascalCase(subject.subject);
|
|
82
96
|
const subjectFolderPath = this.getSubjectFolderRelativePath(subjectFolderName);
|
|
83
97
|
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
this.getAllComponentsFromInterface(screenFileContent, screenInterfaceName, subject) as {
|
|
90
|
-
name: string;
|
|
91
|
-
type: SubjectAgnosticComponents;
|
|
92
|
-
context: string;
|
|
93
|
-
}[];
|
|
94
|
-
|
|
95
|
-
this.addScreenInterfaceImport(subjectClass, screenInterfaceName);
|
|
96
|
-
this.removeComponentImports(subjectClass);
|
|
97
|
-
this.addCoreComponentImports(componentDictionary, subjectFolderName, subjectClass);
|
|
98
|
-
this.addClassExport(subjectClass, screenInterfaceName);
|
|
99
|
-
this.addComponentDeclarations(subjectClass, componentDictionary, subjectFolderName);
|
|
100
|
-
this.addConstructor(subjectClass, componentDictionary, subjectFolderName, subject);
|
|
101
|
-
this.addGoToMethod(subjectClass, subject);
|
|
102
|
-
this.addSubjectClassLineEndings(subjectClass);
|
|
103
|
-
this.verifyDirectoryExists(subjectFolderPath);
|
|
104
|
-
fs.writeFileSync(path.join(subjectFolderPath, `${subjectClass.name}.ts`), subjectClass.content, 'utf-8');
|
|
105
|
-
}
|
|
98
|
+
const componentDictionary = this.getAllComponentsFromInterface(
|
|
99
|
+
screenFileContent,
|
|
100
|
+
screenInterfaceName,
|
|
101
|
+
subject
|
|
102
|
+
) as ComponentEntry[];
|
|
106
103
|
|
|
107
|
-
|
|
108
|
-
|
|
104
|
+
const model = this._modelBuilder.build(subject, screenInterfaceName, componentDictionary, subjectFolderName);
|
|
105
|
+
const content = serializeTsFile(model);
|
|
109
106
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
107
|
+
this.verifyDirectoryExists(subjectFolderPath);
|
|
108
|
+
const className = this._namingHandler.generateSubjectClassName(subject);
|
|
109
|
+
fs.writeFileSync(path.join(subjectFolderPath, `${className}.ts`), content, 'utf-8');
|
|
113
110
|
}
|
|
114
111
|
|
|
115
112
|
private getAllComponentsFromInterface(
|
|
@@ -126,10 +123,17 @@ export class SubjectGenerator {
|
|
|
126
123
|
if (interfaceMatches) {
|
|
127
124
|
const propertyMatches = interfaceMatches[1].match(/^\s*([a-zA-Z0-9_]+)\s*:\s*([a-zA-Z0-9_]+);/gm);
|
|
128
125
|
if (propertyMatches) {
|
|
126
|
+
const screenMeta = new DataRetriever(this._paths).getScreenComponentMeta(subject.screentype_id);
|
|
127
|
+
|
|
129
128
|
componentDictionary = propertyMatches.map((line) => {
|
|
130
129
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
131
130
|
const [_, name, type] = line.match(/^\s*([a-zA-Z0-9_]+)\s*:\s*([a-zA-Z0-9_]+);/) || [];
|
|
132
|
-
const context = this.generateComponentContextLocatorString(
|
|
131
|
+
const context = this.generateComponentContextLocatorString(
|
|
132
|
+
type as ScreenComponents,
|
|
133
|
+
name,
|
|
134
|
+
subject,
|
|
135
|
+
screenMeta
|
|
136
|
+
);
|
|
133
137
|
|
|
134
138
|
return { name, type, context };
|
|
135
139
|
});
|
|
@@ -139,44 +143,23 @@ export class SubjectGenerator {
|
|
|
139
143
|
return componentDictionary;
|
|
140
144
|
}
|
|
141
145
|
|
|
142
|
-
// ToDo: decide if this needs to move into a ContextGenerator class (depending on the complexity of context generation)
|
|
143
146
|
private generateComponentContextLocatorString(
|
|
144
147
|
componentType: ScreenComponents,
|
|
145
148
|
componentName: string,
|
|
146
|
-
subject: ISubject
|
|
149
|
+
subject: ISubject,
|
|
150
|
+
screenMeta: Record<string, string>
|
|
147
151
|
): string {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
switch (componentType) {
|
|
157
|
-
case 'Form':
|
|
158
|
-
case 'Grid':
|
|
159
|
-
case 'Splitter':
|
|
160
|
-
case 'FilterForm':
|
|
161
|
-
case 'Scheduler':
|
|
162
|
-
locatorString.prefix = `screen__${screentypeId}__`;
|
|
163
|
-
break;
|
|
164
|
-
case 'ActionBar':
|
|
165
|
-
case 'CustomActionBar':
|
|
166
|
-
locatorString.prefix = '.';
|
|
167
|
-
locatorString.locatorType = 'locator';
|
|
168
|
-
break;
|
|
169
|
-
case 'Tab':
|
|
170
|
-
locatorString.prefix = '.Tab.';
|
|
171
|
-
locatorString.locatorType = 'locator';
|
|
172
|
-
break;
|
|
173
|
-
case 'DetailTabPage':
|
|
174
|
-
return `this.context`;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
return `this.context.${locatorString.locatorType}('${locatorString.prefix}${componentId}${locatorString.suffix}')`;
|
|
152
|
+
return generateComponentContextLocatorString(
|
|
153
|
+
componentType,
|
|
154
|
+
componentName,
|
|
155
|
+
subject,
|
|
156
|
+
screenMeta,
|
|
157
|
+
this._namingHandler
|
|
158
|
+
);
|
|
178
159
|
}
|
|
179
160
|
|
|
161
|
+
// ── Helpers ───────────────────────────────────────────────────────────────
|
|
162
|
+
|
|
180
163
|
private verifyDirectoryExists(directoryPath: string): void {
|
|
181
164
|
if (!fs.existsSync(directoryPath)) {
|
|
182
165
|
fs.mkdirSync(directoryPath, { recursive: true });
|
|
@@ -184,10 +167,7 @@ export class SubjectGenerator {
|
|
|
184
167
|
}
|
|
185
168
|
|
|
186
169
|
private getScreenInterfacePath(screenInterfaceName: string): string {
|
|
187
|
-
const screenInterfacePath = path.
|
|
188
|
-
this._currentDirname,
|
|
189
|
-
`../../test-artifacts/screens/${screenInterfaceName}.ts`
|
|
190
|
-
);
|
|
170
|
+
const screenInterfacePath = path.join(this._screensDirectory, `${screenInterfaceName}.ts`);
|
|
191
171
|
|
|
192
172
|
if (!fs.existsSync(screenInterfacePath)) {
|
|
193
173
|
throw new Error(`Screen interface file not found: ${screenInterfacePath}`);
|
|
@@ -197,152 +177,59 @@ export class SubjectGenerator {
|
|
|
197
177
|
}
|
|
198
178
|
|
|
199
179
|
private getSubjectFolderRelativePath(subjectFolderName: string): string {
|
|
200
|
-
|
|
201
|
-
this._currentDirname,
|
|
202
|
-
`../../${SubjectGenerator.SUBJECTS_RELATIVE_PATH}/${subjectFolderName}`
|
|
203
|
-
);
|
|
204
|
-
return subjectFolderPath;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
private addCoreComponentImports(
|
|
208
|
-
componentDictionary: { name: string; type: SubjectAgnosticComponents }[],
|
|
209
|
-
subjectFolderName: string,
|
|
210
|
-
subjectClass: { content: string }
|
|
211
|
-
): void {
|
|
212
|
-
const coreComponentImports = new Set<string>();
|
|
213
|
-
|
|
214
|
-
componentDictionary.forEach((component) => {
|
|
215
|
-
if (!screenComponents.includes(component.type)) return;
|
|
216
|
-
|
|
217
|
-
if (coreComponents.includes(component.type)) {
|
|
218
|
-
const importRegex = new RegExp(
|
|
219
|
-
`import \\{[^}]*\\b${component.type}\\b[^}]*\\} from '../../../components/index.js';`
|
|
220
|
-
);
|
|
221
|
-
|
|
222
|
-
if (importRegex.test(subjectClass.content)) {
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
coreComponentImports.add(component.type);
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
const componentName = component.type;
|
|
231
|
-
const componentImport = `import { type ${subjectFolderName}${componentName}, ${subjectFolderName}${componentName}Component } from './Components/${subjectFolderName}${componentName}.js';`;
|
|
232
|
-
|
|
233
|
-
if (!subjectClass.content.includes(componentImport)) {
|
|
234
|
-
subjectClass.content = `${componentImport}\n${subjectClass.content}`;
|
|
235
|
-
}
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
if (coreComponentImports.size > 0) {
|
|
239
|
-
subjectClass.content = `import { ${Array.from(coreComponentImports).join(', ')} } from '../../../components/index.js';\n${subjectClass.content}`;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
private removeComponentImports(subjectClass: { content: string }): void {
|
|
244
|
-
subjectClass.content = subjectClass.content.replace(
|
|
245
|
-
/import \{[^}]+\} from '\.\.\/\.\.\/components\/index\.js';\n?/g,
|
|
246
|
-
''
|
|
247
|
-
);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
private addClassExport(subjectClass: { content: string; name: string }, screenInterfaceName: string): void {
|
|
251
|
-
subjectClass.content += `\nexport class ${subjectClass.name} extends SubjectPageBase implements ${screenInterfaceName} {\n`;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
private addScreenInterfaceImport(subjectClass: { content: string }, screenInterfaceName: string): void {
|
|
255
|
-
if (subjectClass.content.includes(`import type { ${screenInterfaceName} }`)) {
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
subjectClass.content = `import type { ${screenInterfaceName} } from '../../screens/index.js';\n${subjectClass.content}`;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
private addComponentDeclarations(
|
|
263
|
-
subjectClass: { content: string },
|
|
264
|
-
componentDictionary: { name: string; type: SubjectAgnosticComponents }[],
|
|
265
|
-
subjectFolderName: string
|
|
266
|
-
): void {
|
|
267
|
-
componentDictionary.forEach((component) => {
|
|
268
|
-
if (!screenComponents.includes(component.type)) return;
|
|
269
|
-
|
|
270
|
-
const propertyName = this._namingHandler.formatPropertyName(component.name);
|
|
271
|
-
if (coreComponents.includes(component.type)) {
|
|
272
|
-
subjectClass.content += ` ${propertyName}: ${component.type};\n`;
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
const componentType = `${subjectFolderName}${component.type}`;
|
|
276
|
-
subjectClass.content += ` ${propertyName}: ${componentType};\n`;
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
subjectClass.content += ` private _subjectPage: Page;\n`;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
private addConstructor(
|
|
283
|
-
subjectClass: { content: string },
|
|
284
|
-
componentDictionary: { name: string; type: SubjectAgnosticComponents; context: string }[],
|
|
285
|
-
subjectFolderName: string,
|
|
286
|
-
subject: ISubject
|
|
287
|
-
): void {
|
|
288
|
-
const rootContextSelector = this._selectorBuilder.getPageContext(subject);
|
|
289
|
-
|
|
290
|
-
subjectClass.content += `\n constructor(page: Page) {\n super(page.locator('${rootContextSelector}'));\n`;
|
|
291
|
-
|
|
292
|
-
componentDictionary.forEach((component) => {
|
|
293
|
-
const propertyName = this._namingHandler.formatPropertyName(component.name);
|
|
294
|
-
|
|
295
|
-
if (!screenComponents.includes(component.type)) return;
|
|
296
|
-
|
|
297
|
-
if (coreComponents.includes(component.type)) {
|
|
298
|
-
const componentId = this._namingHandler.toPascalCase(propertyName);
|
|
299
|
-
subjectClass.content += ` this.${propertyName} = ${this.getComponentInitializer(component, componentId)};\n`;
|
|
300
|
-
return;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
const componentName = component.type;
|
|
304
|
-
subjectClass.content += ` this.${propertyName} = new ${subjectFolderName}${componentName}Component(${component.context});\n`;
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
subjectClass.content += ` this._subjectPage = this.context.page();\n`;
|
|
308
|
-
subjectClass.content += ` }\n`;
|
|
180
|
+
return this._paths.subjectFolder(subjectFolderName);
|
|
309
181
|
}
|
|
182
|
+
}
|
|
310
183
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
184
|
+
/**
|
|
185
|
+
* Builds the Playwright locator expression string for a given screen component.
|
|
186
|
+
*
|
|
187
|
+
* Exported as a standalone function so that it can be unit-tested independently
|
|
188
|
+
* of the file-I/O-coupled {@link SubjectGenerator} class.
|
|
189
|
+
*/
|
|
190
|
+
export function generateComponentContextLocatorString(
|
|
191
|
+
componentType: ScreenComponents,
|
|
192
|
+
componentName: string,
|
|
193
|
+
subject: ISubject,
|
|
194
|
+
screenMeta: Record<string, string>,
|
|
195
|
+
namingHandler: NamingHandler
|
|
196
|
+
): string {
|
|
197
|
+
// Normalize the quicktype property name to the same form used as key in the meta map.
|
|
198
|
+
const normalizedName = componentName.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
199
|
+
const originalId = screenMeta[normalizedName];
|
|
200
|
+
|
|
201
|
+
const screentypeId = subject.screentype_id.replace(/_/g, '-');
|
|
202
|
+
const locatorString = {
|
|
203
|
+
prefix: '',
|
|
204
|
+
locatorType: 'getByTestId' as LocatorType
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
switch (componentType) {
|
|
208
|
+
case 'Form':
|
|
209
|
+
case 'Grid':
|
|
210
|
+
case 'Splitter':
|
|
211
|
+
case 'FilterForm':
|
|
212
|
+
case 'Scheduler': {
|
|
213
|
+
// data-testid uses lowercase with hyphens: e.g. Grid_QT3UL7F8 → grid-qt3ul7f8
|
|
214
|
+
const testId = originalId ? originalId.toLowerCase().replace(/_/g, '-') : componentName.toLowerCase();
|
|
215
|
+
locatorString.prefix = `screen__${screentypeId}__`;
|
|
216
|
+
return `this.context.getByTestId('${locatorString.prefix}${testId}')`;
|
|
342
217
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
218
|
+
case 'ActionBar':
|
|
219
|
+
case 'CustomActionBar':
|
|
220
|
+
locatorString.prefix = '.';
|
|
221
|
+
locatorString.locatorType = 'locator';
|
|
222
|
+
break;
|
|
223
|
+
case 'Tab':
|
|
224
|
+
locatorString.prefix = '.Tab.';
|
|
225
|
+
locatorString.locatorType = 'locator';
|
|
226
|
+
break;
|
|
227
|
+
case 'DetailTabPage':
|
|
228
|
+
return `this.context`;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// For CSS class selectors (ActionBar, Tab): use the original ID as-is, fall back to
|
|
232
|
+
// capitalizing the first letter (handles consolidated 'tab' / 'detailTab' properties).
|
|
233
|
+
const cssId = originalId ?? namingHandler.capitalizeFirstLetter(componentName);
|
|
234
|
+
return `this.context.${locatorString.locatorType}('${locatorString.prefix}${cssId}')`;
|
|
348
235
|
}
|
|
@@ -1,20 +1,39 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
|
-
import { dirname } from 'node:path';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
3
|
import * as prettier from 'prettier';
|
|
6
|
-
|
|
4
|
+
import type { ISubjectDetail, ScreenContext } from '../interfaces/ISubjectDetail.js';
|
|
5
|
+
import { PipelinePaths } from './helpers/PipelinePaths.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* **Pipeline Step 7** — Registers all generated subject classes into
|
|
9
|
+
* `page-extensions/SubjectRegistry.ts` so they are available on
|
|
10
|
+
* `page.subject.<ClassName>` during tests.
|
|
11
|
+
*
|
|
12
|
+
* **What it does:**
|
|
13
|
+
* - Scans `test-artifacts/subjects/` to discover every generated class file.
|
|
14
|
+
* - Reads `templates/SubjectRegistry.template.ts` as the implementation skeleton.
|
|
15
|
+
* - Injects import statements and property declarations for every discovered
|
|
16
|
+
* class into the template and writes the result to
|
|
17
|
+
* `page-extensions/SubjectRegistry.ts`.
|
|
18
|
+
* - Runs `prettier` over the output so the generated file passes lint.
|
|
19
|
+
*
|
|
20
|
+
* **Important:** Never edit `SubjectRegistry.ts` directly — it is
|
|
21
|
+
* overwritten on every `testwise sync`. Edit the template instead.
|
|
22
|
+
*
|
|
23
|
+
* **When it runs:** The final step (step 7) of `testwise sync`.
|
|
24
|
+
*/
|
|
7
25
|
export class SubjectRegistration {
|
|
8
26
|
private static readonly IMPORT_MATCH_REGEX = /import .*'\.\.\/test-artifacts\/subjects\/index\.js';\n?/g;
|
|
9
27
|
|
|
10
|
-
private readonly _currentFilename: string;
|
|
11
|
-
private readonly _currentDirname: string;
|
|
12
28
|
private readonly _subjectTypePath: string;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
29
|
+
private readonly _subjectsDirectory: string;
|
|
30
|
+
private readonly _registryTemplatePath: string;
|
|
31
|
+
|
|
32
|
+
constructor(paths?: PipelinePaths) {
|
|
33
|
+
const p = paths ?? new PipelinePaths();
|
|
34
|
+
this._subjectTypePath = p.subjectRegistry;
|
|
35
|
+
this._subjectsDirectory = p.subjects;
|
|
36
|
+
this._registryTemplatePath = p.subjectRegistryTemplate;
|
|
18
37
|
}
|
|
19
38
|
|
|
20
39
|
public async run(): Promise<void> {
|
|
@@ -24,20 +43,16 @@ export class SubjectRegistration {
|
|
|
24
43
|
}
|
|
25
44
|
|
|
26
45
|
public resetSubjectRegistry(): void {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const templatePath = path.join(root, 'templates', 'SubjectRegistry.template.ts');
|
|
30
|
-
|
|
31
|
-
if (fs.existsSync(registryPath)) {
|
|
32
|
-
fs.rmSync(registryPath, { force: true });
|
|
46
|
+
if (fs.existsSync(this._subjectTypePath)) {
|
|
47
|
+
fs.rmSync(this._subjectTypePath, { force: true });
|
|
33
48
|
}
|
|
34
49
|
|
|
35
|
-
if (fs.existsSync(
|
|
36
|
-
fs.copyFileSync(
|
|
50
|
+
if (fs.existsSync(this._registryTemplatePath)) {
|
|
51
|
+
fs.copyFileSync(this._registryTemplatePath, this._subjectTypePath);
|
|
37
52
|
}
|
|
38
53
|
}
|
|
39
54
|
|
|
40
|
-
private async registerGeneratedSubjectsAsSubjectTypes(subjectDetails:
|
|
55
|
+
private async registerGeneratedSubjectsAsSubjectTypes(subjectDetails: ISubjectDetail[]): Promise<void> {
|
|
41
56
|
const subjectTypeImportsAndExports = this.buildSubjectTypeExport(subjectDetails);
|
|
42
57
|
const subject = { content: this.setSubjectTypeContent() };
|
|
43
58
|
|
|
@@ -75,7 +90,7 @@ export class SubjectRegistration {
|
|
|
75
90
|
}
|
|
76
91
|
}
|
|
77
92
|
|
|
78
|
-
private buildSubjectTypeExport(subjectDetails:
|
|
93
|
+
private buildSubjectTypeExport(subjectDetails: ISubjectDetail[]): string {
|
|
79
94
|
const subjectTypeEntries = subjectDetails
|
|
80
95
|
.map(
|
|
81
96
|
(details) =>
|
|
@@ -91,13 +106,13 @@ export class SubjectRegistration {
|
|
|
91
106
|
return newSubjectTypes;
|
|
92
107
|
}
|
|
93
108
|
|
|
94
|
-
private addPathRecordsToContent(content: string, subjectDetails:
|
|
109
|
+
private addPathRecordsToContent(content: string, subjectDetails: ISubjectDetail[]): string {
|
|
95
110
|
const pathRecordsString = this.buildPathRecordsString(subjectDetails);
|
|
96
111
|
const stringToMatch = "none: ''";
|
|
97
112
|
return content.replace(stringToMatch, `\n${pathRecordsString}\n `);
|
|
98
113
|
}
|
|
99
114
|
|
|
100
|
-
private buildPathRecordsString(subjectDetails:
|
|
115
|
+
private buildPathRecordsString(subjectDetails: ISubjectDetail[]): string {
|
|
101
116
|
return subjectDetails
|
|
102
117
|
.map(
|
|
103
118
|
(details) =>
|
|
@@ -107,14 +122,14 @@ export class SubjectRegistration {
|
|
|
107
122
|
.join('\n ');
|
|
108
123
|
}
|
|
109
124
|
|
|
110
|
-
private getAllSubjectDetails():
|
|
111
|
-
const subjectsDir =
|
|
125
|
+
private getAllSubjectDetails(): ISubjectDetail[] {
|
|
126
|
+
const subjectsDir = this._subjectsDirectory;
|
|
112
127
|
|
|
113
128
|
const subjectFolders = fs.readdirSync(subjectsDir).filter((file) => {
|
|
114
129
|
return fs.statSync(path.join(subjectsDir, file)).isDirectory();
|
|
115
130
|
});
|
|
116
131
|
|
|
117
|
-
const subjectDetails:
|
|
132
|
+
const subjectDetails: ISubjectDetail[] = [];
|
|
118
133
|
const seenFullNames = new Set<string>();
|
|
119
134
|
|
|
120
135
|
subjectFolders.forEach((folder) => {
|
|
@@ -134,7 +149,7 @@ export class SubjectRegistration {
|
|
|
134
149
|
const fullName = variantMatch[0];
|
|
135
150
|
if (!seenFullNames.has(fullName)) {
|
|
136
151
|
const variant = variantMatch[2] || '';
|
|
137
|
-
const screen = variantMatch[3] as
|
|
152
|
+
const screen = variantMatch[3] as ScreenContext;
|
|
138
153
|
|
|
139
154
|
subjectDetails.push({
|
|
140
155
|
subject: folder,
|
|
@@ -150,9 +165,3 @@ export class SubjectRegistration {
|
|
|
150
165
|
return subjectDetails;
|
|
151
166
|
}
|
|
152
167
|
}
|
|
153
|
-
|
|
154
|
-
export interface SubjectDetail {
|
|
155
|
-
subject: string;
|
|
156
|
-
variant?: string;
|
|
157
|
-
screen: 'Main' | 'Popup' | 'Zoom' | 'Detail';
|
|
158
|
-
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a single named import member.
|
|
3
|
+
* Set `isTypeOnly` for inline `type` keyword, e.g. `import { type IFoo, Bar }`.
|
|
4
|
+
*/
|
|
5
|
+
export interface TsNamedImport {
|
|
6
|
+
name: string;
|
|
7
|
+
isTypeOnly?: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Represents a single import statement in a TypeScript file.
|
|
12
|
+
* Set `isTypeOnly` at the top level for `import type { ... }`.
|
|
13
|
+
*/
|
|
14
|
+
export interface TsImport {
|
|
15
|
+
namedImports: TsNamedImport[];
|
|
16
|
+
isTypeOnly: boolean;
|
|
17
|
+
from: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Represents a class property declaration. */
|
|
21
|
+
export interface TsProperty {
|
|
22
|
+
access?: 'private';
|
|
23
|
+
name: string;
|
|
24
|
+
type: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Represents a `this.x = value;` assignment inside a constructor. */
|
|
28
|
+
export interface TsConstructorAssignment {
|
|
29
|
+
property: string;
|
|
30
|
+
value: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Represents a class constructor. */
|
|
34
|
+
export interface TsConstructor {
|
|
35
|
+
params: Array<{ name: string; type: string }>;
|
|
36
|
+
superCall: string;
|
|
37
|
+
assignments: TsConstructorAssignment[];
|
|
38
|
+
extraLines: string[];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Represents a class method. */
|
|
42
|
+
export interface TsMethod {
|
|
43
|
+
isAsync: boolean;
|
|
44
|
+
name: string;
|
|
45
|
+
returnType: string;
|
|
46
|
+
bodyLines: string[];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Represents a TypeScript class declaration. */
|
|
50
|
+
export interface TsClass {
|
|
51
|
+
name: string;
|
|
52
|
+
extendsClass: string;
|
|
53
|
+
implementsInterface: string;
|
|
54
|
+
properties: TsProperty[];
|
|
55
|
+
constructor: TsConstructor;
|
|
56
|
+
methods?: TsMethod[];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Top-level model for a generated TypeScript subject class file. */
|
|
60
|
+
export interface TsFileModel {
|
|
61
|
+
imports: TsImport[];
|
|
62
|
+
classModel: TsClass;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Represents a typed property in a component class. */
|
|
66
|
+
export interface ComponentPropertyModel {
|
|
67
|
+
name: string;
|
|
68
|
+
type: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Represents a `this.x = value;` assignment in a component class constructor. */
|
|
72
|
+
export interface ComponentAssignmentModel {
|
|
73
|
+
property: string;
|
|
74
|
+
value: string;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Represents a getter in a Grid component class. */
|
|
78
|
+
export interface ComponentGetterModel {
|
|
79
|
+
name: string;
|
|
80
|
+
returnType: string;
|
|
81
|
+
bodyLine: string;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Represents the class body to append to a component interface file.
|
|
86
|
+
* Properties and assignments apply to Form; getters apply to Grid.
|
|
87
|
+
*/
|
|
88
|
+
export interface ComponentClassModel {
|
|
89
|
+
interfaceName: string;
|
|
90
|
+
componentType: string;
|
|
91
|
+
properties: ComponentPropertyModel[];
|
|
92
|
+
assignments: ComponentAssignmentModel[];
|
|
93
|
+
getters: ComponentGetterModel[];
|
|
94
|
+
}
|