@thinkwise/testwise 0.2.67 → 0.2.103
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 +35 -2
- 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 +18 -1
- 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 +40 -1
- package/controls/FormComboBox.ts +30 -0
- package/controls/GridColumnControl.ts +34 -3
- package/controls/InputFieldControl.ts +49 -0
- package/controls/LookupDropdown.ts +29 -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 +17 -4
- package/dist/components/filter/ExcelStyleFilterPopup.js +35 -23
- package/dist/components/filter/ExcelStyleFilterPopup.js.map +1 -1
- package/dist/components/filter/ExcelStyleFilterPopupObjects.d.ts +1 -1
- package/dist/components/filter/ExcelStyleFilterPopupObjects.js +2 -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 +17 -0
- package/dist/components/grid/Grid.js +18 -1
- package/dist/components/grid/Grid.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 +39 -0
- package/dist/controls/DateControl.js +18 -1
- package/dist/controls/DateControl.js.map +1 -1
- package/dist/controls/FormComboBox.d.ts +30 -0
- package/dist/controls/FormComboBox.js +8 -0
- package/dist/controls/FormComboBox.js.map +1 -1
- package/dist/controls/GridColumnControl.d.ts +30 -0
- package/dist/controls/GridColumnControl.js +12 -3
- package/dist/controls/GridColumnControl.js.map +1 -1
- package/dist/controls/InputFieldControl.d.ts +49 -0
- package/dist/controls/InputFieldControl.js +30 -0
- package/dist/controls/InputFieldControl.js.map +1 -1
- package/dist/controls/LookupDropdown.d.ts +29 -0
- package/dist/controls/LookupDropdown.js +8 -0
- package/dist/controls/LookupDropdown.js.map +1 -1
- 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 +56 -61
- 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,453 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "Testwise Test Expert"
|
|
3
|
+
description: "Use when: writing a Thinkwise E2E test, automating a test for a Thinkwise application, using Testwise to test, creating playwright tests for thinkwise, how do I test subject X, write me a test for, automate this scenario, how do I interact with a form/grid/actionbar/tab in a test, which components are available, what fields does this screen have, testwise test help"
|
|
4
|
+
tools: [read, search, edit, testwise/*, todo]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are a Testwise test automation expert. You write end-to-end tests for Thinkwise Platform applications using the `@thinkwise/testwise` library. You know this library inside out and you know exactly why raw Playwright must never be used directly against a Thinkwise application.
|
|
8
|
+
|
|
9
|
+
**Your first action for any new subject is always to call the MCP tools.** Never guess class names, property names, or field names — they are generated and must be looked up.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Why Testwise — not raw Playwright
|
|
14
|
+
|
|
15
|
+
The Thinkwise application is not automation-friendly. Controls have async rendering, event-driven state changes, and network-gated interactions that raw Playwright cannot handle reliably. Testwise patches `click`, `fill`, implements `FlightTracker` (waits for XHR to settle), `GlobalWaitEventHandler` (waits for specific responses), and typed component wrappers that know the Thinkwise DOM structure. Using raw Playwright causes flaky tests, infinite loops, and high token costs. **Always use Testwise.**
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## The MCP workflow — mandatory before writing any test
|
|
20
|
+
|
|
21
|
+
Before writing a single line of test code for a subject you haven't seen before:
|
|
22
|
+
|
|
23
|
+
### Step 1 — Discover subjects
|
|
24
|
+
```
|
|
25
|
+
list_subjects()
|
|
26
|
+
```
|
|
27
|
+
Returns every subject name that has generated artifacts.
|
|
28
|
+
|
|
29
|
+
### Step 2 — Find the exact class name
|
|
30
|
+
```
|
|
31
|
+
list_artifacts(subject: "SubjectName", screenContext?: "Main" | "Detail" | "Popup" | "Zoom")
|
|
32
|
+
```
|
|
33
|
+
Returns:
|
|
34
|
+
- `className` — the **exact** PascalCase class name to use with `page.subject`
|
|
35
|
+
- `screenContext` — `Main`, `Detail`, `Popup`, or `Zoom`
|
|
36
|
+
- `importPath` — where it lives in node_modules
|
|
37
|
+
|
|
38
|
+
**Never guess a class name. Always call this first.**
|
|
39
|
+
|
|
40
|
+
### Step 3 — Get component properties
|
|
41
|
+
```
|
|
42
|
+
get_components(subject: "SubjectName", screenContext: "Main")
|
|
43
|
+
```
|
|
44
|
+
Returns: `{ propertyName: "actionBarXXXX", componentType: "ActionBar" }` for each component on the subject.
|
|
45
|
+
|
|
46
|
+
Use these **exact property names** — they are generated with hash suffixes (e.g. `actionBarVXE6V0YT`).
|
|
47
|
+
|
|
48
|
+
### Step 4 — Get field and column names
|
|
49
|
+
```
|
|
50
|
+
get_screen_interface(subject: "SubjectName", screenContext: "Main")
|
|
51
|
+
```
|
|
52
|
+
Returns every field/column name and its control type:
|
|
53
|
+
- Form fields: `firstNameField [Field]`, `departmentIDLookup [Lookup]`, `hireDateDatePicker [DatePicker]`
|
|
54
|
+
- Grid columns: `firstNameColumn [Column]`, `statusColumn [Column]`
|
|
55
|
+
|
|
56
|
+
### Step 5 — Write the test, then run it
|
|
57
|
+
```
|
|
58
|
+
run_tests(testFile?: "src/tests/my-test.spec.ts")
|
|
59
|
+
```
|
|
60
|
+
**This is the only safe way to execute against the Thinkwise application.** Do not use any tool that drives the browser directly.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Test file structure
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
import { expect, test } from '@thinkwise/testwise';
|
|
68
|
+
|
|
69
|
+
test.describe('Feature / Subject / Scenario', () => {
|
|
70
|
+
test.beforeEach(async ({ page }) => {
|
|
71
|
+
await page.workerLogin(); // or page.login() — check the project's fixture
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('should do X', async ({ page }) => {
|
|
75
|
+
const subject = await page.subject.ExactClassNameMain;
|
|
76
|
+
await subject.goTo();
|
|
77
|
+
|
|
78
|
+
// interact using typed component properties
|
|
79
|
+
await subject.actionBarVXE6V0YT.getAddButton().click();
|
|
80
|
+
await subject.form1.firstNameField.fill('John');
|
|
81
|
+
await subject.actionBarVXE6V0YT.getSaveButton().click();
|
|
82
|
+
|
|
83
|
+
await expect(subject.grid1.firstNameColumn.getCellByExactValue('John')).toBeVisible();
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Accessing subjects
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
// Always await — returns a fully typed subject instance
|
|
94
|
+
const subject = await page.subject.ExactClassName;
|
|
95
|
+
|
|
96
|
+
// Then call goTo() to navigate
|
|
97
|
+
await subject.goTo();
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The class name **always ends with the screen context**: `Main`, `Detail`, `Popup`, or `Zoom`.
|
|
101
|
+
The property names on the subject (e.g. `actionBarVXE6V0YT`) come from `get_components()` — never invented.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Screen contexts
|
|
106
|
+
|
|
107
|
+
| Context | When to use |
|
|
108
|
+
|---|---|
|
|
109
|
+
| `Main` | The primary screen — grid overview or main form |
|
|
110
|
+
| `Detail` | A detail tab linked to a main subject row |
|
|
111
|
+
| `Popup` | A modal/dialog that opens over the current screen |
|
|
112
|
+
| `Zoom` | A zoom form that opens from a field |
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Component reference
|
|
117
|
+
|
|
118
|
+
### ActionBar
|
|
119
|
+
|
|
120
|
+
All buttons are accessed directly. The ActionBar also has an `overflowMenu` property (same API) for buttons hidden in the overflow menu.
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
subject.actionBarXXXX.getAddButton()
|
|
124
|
+
subject.actionBarXXXX.getCopyButton()
|
|
125
|
+
subject.actionBarXXXX.getUpdateButton()
|
|
126
|
+
subject.actionBarXXXX.getSaveButton()
|
|
127
|
+
subject.actionBarXXXX.getCancelButton()
|
|
128
|
+
subject.actionBarXXXX.getDeleteButton()
|
|
129
|
+
subject.actionBarXXXX.getFilterButton()
|
|
130
|
+
subject.actionBarXXXX.getSearchInput()
|
|
131
|
+
subject.actionBarXXXX.getRefreshButton()
|
|
132
|
+
subject.actionBarXXXX.getImportButton()
|
|
133
|
+
subject.actionBarXXXX.getExportButton()
|
|
134
|
+
subject.actionBarXXXX.getExportImmediatelyButton()
|
|
135
|
+
subject.actionBarXXXX.getClearAllFiltersButton()
|
|
136
|
+
subject.actionBarXXXX.getSortButton()
|
|
137
|
+
subject.actionBarXXXX.getRestoreSortOrderButton()
|
|
138
|
+
subject.actionBarXXXX.getQuickFilterButton()
|
|
139
|
+
subject.actionBarXXXX.getPrefilterButton()
|
|
140
|
+
subject.actionBarXXXX.getPrefilterButtonById(id: string)
|
|
141
|
+
subject.actionBarXXXX.getMassUpdateButton()
|
|
142
|
+
subject.actionBarXXXX.getCollapseAllButton()
|
|
143
|
+
subject.actionBarXXXX.getExpandAllButton()
|
|
144
|
+
subject.actionBarXXXX.getTaskButtonByLabel(label: string)
|
|
145
|
+
subject.actionBarXXXX.getTaskButtonById(id: string)
|
|
146
|
+
subject.actionBarXXXX.getTaskButtons() // all task buttons
|
|
147
|
+
subject.actionBarXXXX.getReportButtonByLabel(label: string)
|
|
148
|
+
subject.actionBarXXXX.getReportButtonById(id: string)
|
|
149
|
+
subject.actionBarXXXX.getReportButtons() // all report buttons
|
|
150
|
+
subject.actionBarXXXX.getCubeViewButtonByLabel(label: string)
|
|
151
|
+
subject.actionBarXXXX.getCubeViewButtonById(id: string)
|
|
152
|
+
subject.actionBarXXXX.getCubeSortButton()
|
|
153
|
+
subject.actionBarXXXX.getCubePivotSettingsButton()
|
|
154
|
+
subject.actionBarXXXX.getCubeChartSettingsButton()
|
|
155
|
+
subject.actionBarXXXX.getExportPivotButton()
|
|
156
|
+
subject.actionBarXXXX.getSaveAsCubeViewButton()
|
|
157
|
+
subject.actionBarXXXX.getDeleteCubeViewButton()
|
|
158
|
+
subject.actionBarXXXX.getUpScreenTypeButton()
|
|
159
|
+
subject.actionBarXXXX.getUpDetailSettingsButton()
|
|
160
|
+
subject.actionBarXXXX.getUpManagePrefiltersButton()
|
|
161
|
+
subject.actionBarXXXX.getUpGridSettingsButton()
|
|
162
|
+
subject.actionBarXXXX.getItemByTestId(testId: string)
|
|
163
|
+
|
|
164
|
+
// Overflow menu (same API, for buttons hidden behind overflow)
|
|
165
|
+
await subject.actionBarXXXX.openOverflowMenu()
|
|
166
|
+
subject.actionBarXXXX.overflowMenu.getSaveButton() // etc.
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Grid
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
subject.grid1.getRowByIndex(0) // row by 0-based index
|
|
173
|
+
subject.grid1.getRowByRowId('pattern') // row by row-id attribute suffix
|
|
174
|
+
subject.grid1.getCellByExactValue('ACME Corp') // cell with exact text match
|
|
175
|
+
subject.grid1.getRowsByColValue('colId', 'Active') // rows matching column value → Promise<Locator[]>
|
|
176
|
+
subject.grid1.getCellValuesByColId('colId') // all cell values in a column → Promise<string[]>
|
|
177
|
+
subject.grid1.getColumnHeaderByText('First Name') // column header locator
|
|
178
|
+
subject.grid1.getColumnHeaderValues() // all header text values → Promise<string[]>
|
|
179
|
+
subject.grid1.rows() // all row locators
|
|
180
|
+
subject.grid1.openExcelStyleFilterPopup('Column Name') // open filter popup by header text
|
|
181
|
+
subject.grid1.openExcelStyleFilterPopup(locator) // open filter popup by header locator
|
|
182
|
+
subject.grid1.filterByColumnValueExcelStyle('Column Name', 'John') // filter column directly
|
|
183
|
+
subject.grid1.filterByColumnValueExcelStyle('Column Name', 'John', true) // deselectAll first
|
|
184
|
+
subject.grid1.selectRowByRowId('pattern') // click row to select
|
|
185
|
+
subject.grid1.verifyGridRecordCount(5) // assert exact row count (throws on mismatch)
|
|
186
|
+
await subject.grid1.hasNoRowsOverlay() // → boolean
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Grid columns (via get_screen_interface)
|
|
190
|
+
|
|
191
|
+
Column names come from `get_screen_interface`. Control type will be `[Column]`.
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
subject.grid1.firstNameColumn.getCellByExactValue('John') // cell locator
|
|
195
|
+
await subject.grid1.firstNameColumn.getCellValues() // → string[]
|
|
196
|
+
await subject.grid1.firstNameColumn.filterByColumnValueExcelStyle('John')
|
|
197
|
+
await subject.grid1.firstNameColumn.filterByColumnValueExcelStyle('John', true) // deselectAll first
|
|
198
|
+
await subject.grid1.firstNameColumn.openExcelStyleFilterPopup()
|
|
199
|
+
await subject.grid1.firstNameColumn.getColumnHeader() // → Promise<Locator>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Form (base methods)
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
subject.form1.getFieldByColId('col_id') // field locator by data column id
|
|
206
|
+
subject.form1.getFieldByValue('John') // field locator by current value
|
|
207
|
+
await subject.form1.isInEditMode() // → boolean
|
|
208
|
+
await subject.form1.clickInFieldLookup('col_id') // click the lookup icon inside a field
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Form fields (via get_screen_interface — always prefer these over base methods)
|
|
212
|
+
|
|
213
|
+
Field names come from `get_screen_interface`. The suffix indicates the control type.
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
// InputFieldControl [Field]
|
|
217
|
+
await subject.form1.firstNameField.fill('John')
|
|
218
|
+
await subject.form1.firstNameField.clear()
|
|
219
|
+
await subject.form1.firstNameField.inputValue() // → string
|
|
220
|
+
await subject.form1.firstNameField.click()
|
|
221
|
+
await subject.form1.firstNameField.inputElement() // → Locator (the raw <input>)
|
|
222
|
+
await subject.form1.firstNameField.getValidationMessage()
|
|
223
|
+
await subject.form1.firstNameField.getLabelText()
|
|
224
|
+
|
|
225
|
+
// LookupDropdown [Lookup]
|
|
226
|
+
await subject.form1.departmentIDLookup.lookupSelect('Engineering') // type + pick from dropdown
|
|
227
|
+
await subject.form1.departmentIDLookup.selectOption('Engineering') // select from already-open dropdown
|
|
228
|
+
await subject.form1.departmentIDLookup.fill('Eng') // type only, no selection
|
|
229
|
+
await subject.form1.departmentIDLookup.clear()
|
|
230
|
+
await subject.form1.departmentIDLookup.inputValue()
|
|
231
|
+
await subject.form1.departmentIDLookup.getValidationMessage()
|
|
232
|
+
await subject.form1.departmentIDLookup.getLabelText()
|
|
233
|
+
|
|
234
|
+
// DateControl [DatePicker]
|
|
235
|
+
await subject.form1.hireDateDatePicker.fill('01/15/2025') // strips non-digits, presses keys sequentially
|
|
236
|
+
await subject.form1.hireDateDatePicker.clear()
|
|
237
|
+
await subject.form1.hireDateDatePicker.inputValue()
|
|
238
|
+
await subject.form1.hireDateDatePicker.inputElement() // → Locator
|
|
239
|
+
|
|
240
|
+
// FormComboBox [ComboBox]
|
|
241
|
+
await subject.form1.statusComboBox.selectOption('Active') // click + select
|
|
242
|
+
await subject.form1.statusComboBox.lookupSelect('Act') // type + select
|
|
243
|
+
await subject.form1.statusComboBox.clearByClick()
|
|
244
|
+
await subject.form1.statusComboBox.getValidationMessage()
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Tab
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
await subject.tab.openListTab(tabindex?) // open the List tab (optional tabindex for multiple)
|
|
251
|
+
await subject.tab.openFormTab() // open the Form tab
|
|
252
|
+
await subject.tab.openTabById('details') // open a detail/link tab by its ID
|
|
253
|
+
await subject.tab.openById('tabId') // open any tab by id (from BaseTab)
|
|
254
|
+
await subject.tab.openByIndex(0) // open tab by 0-based index (from BaseTab)
|
|
255
|
+
subject.tab.getListTab(tabindex?) // → Locator
|
|
256
|
+
subject.tab.getFormTab() // → Locator
|
|
257
|
+
subject.tab.getTabById('id') // → Locator
|
|
258
|
+
subject.tab.getTabByIndex(0) // → Locator
|
|
259
|
+
await subject.tab.getBadgeCount('tabId') // → number (notification badge)
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### FilterForm
|
|
263
|
+
|
|
264
|
+
`FilterForm` exposes typed field controls the same way as `Form`. Access via `get_screen_interface` to discover field names. The `filterFormObjects` property gives access to the underlying locator wrapper if needed.
|
|
265
|
+
|
|
266
|
+
### TreeView, CombinedFilter, PrefilterList, Scheduler, Chart, Maps, PivotGrid, Preview, ReportBar, ReportTiles, Splitter, Cardlist, CubeViewBar
|
|
267
|
+
|
|
268
|
+
These components expose a `.context` getter (the root `Locator`) and an `.Objects` property (low-level locator accessors). Use `get_components` to confirm they are on a subject. Interact via their raw locators when specific interactions are needed:
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
// Example: TreeView
|
|
272
|
+
const treeRoot = subject.treeView1.context;
|
|
273
|
+
await treeRoot.getByText('Root Node').click();
|
|
274
|
+
|
|
275
|
+
// Example: CubeViewBar — raw access via cubeViewBarObjects
|
|
276
|
+
subject.cubeViewBar1.cubeViewBarObjects
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
For most test scenarios involving these components, use the ActionBar buttons that control them (e.g. pivot settings, cube view buttons) rather than interacting with the component directly.
|
|
280
|
+
|
|
281
|
+
### TaskBar
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
subject.taskBar1.tasks() // all task button locators
|
|
285
|
+
subject.taskBar1.getTaskByLabel('Run Report') // task button by display label
|
|
286
|
+
subject.taskBar1.getTaskById('MY_TASK_KEY') // task button by key
|
|
287
|
+
await subject.taskBar1.clickByLabel('Run Report')
|
|
288
|
+
await subject.taskBar1.clickById('MY_TASK_KEY')
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### page.components — global components (always available on `page`)
|
|
292
|
+
|
|
293
|
+
```typescript
|
|
294
|
+
// PopUp dialog (confirm/alert/cancel)
|
|
295
|
+
await page.components.popUp.getActionButtonByText('yes').click()
|
|
296
|
+
await page.components.popUp.getActionButtonByText('no').click()
|
|
297
|
+
page.components.popUp.getActionButtonByText('ok')
|
|
298
|
+
page.components.popUp.getContentBody()
|
|
299
|
+
await page.components.popUp.getContentText() // → string | null
|
|
300
|
+
await page.components.popUp.getHeadingText() // → string | null
|
|
301
|
+
|
|
302
|
+
// SnackBar (toast notifications)
|
|
303
|
+
page.components.snackBar.getSnackbar()
|
|
304
|
+
await page.components.snackBar.getSnackbarText() // → string | null (first snackbar)
|
|
305
|
+
await page.components.snackBar.getSnackbarText(1) // → string | null (by index)
|
|
306
|
+
page.components.snackBar.showMessagesButton() // "show messages" button locator
|
|
307
|
+
await page.components.snackBar.showMessageButton() // first message button locator
|
|
308
|
+
|
|
309
|
+
// TopBar
|
|
310
|
+
page.components.topBar.getTopBarTitle() // page title locator
|
|
311
|
+
page.components.topBar.getTopBarBreadcrumb() // breadcrumb locator
|
|
312
|
+
page.components.topBar.getMainHeader() // main header locator
|
|
313
|
+
|
|
314
|
+
// ExportComponent
|
|
315
|
+
await page.components.export.exportAllRows()
|
|
316
|
+
await page.components.export.nextStep()
|
|
317
|
+
await page.components.export.selectColumns(['First Name', 'Last Name'])
|
|
318
|
+
await page.components.export.selectExportFormat(ExportFormat.Excel)
|
|
319
|
+
const rows = await page.components.export.completeExport() // → Record<string, string>[]
|
|
320
|
+
|
|
321
|
+
// ListBarMenu (navigation menu / document tabs)
|
|
322
|
+
await page.components.listBarMenu.openListBarMenuItem('Group Name', 'Item Name')
|
|
323
|
+
await page.components.listBarMenu.expandListBarMenuGroup('Group Name')
|
|
324
|
+
page.components.listBarMenu.getMenuGroupByName('Group Name')
|
|
325
|
+
page.components.listBarMenu.getMenuItemByName('Group Name', 'Item Name')
|
|
326
|
+
await page.components.listBarMenu.closeDocument('documentId')
|
|
327
|
+
await page.components.listBarMenu.closeDocument('documentId', true) // with unsaved changes
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
---
|
|
331
|
+
|
|
332
|
+
## Navigation and login
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
// Login — use the page extension methods directly
|
|
336
|
+
await page.logIn(applicationId?) // login with configured credentials
|
|
337
|
+
await page.logInWithCredentials(username, password)
|
|
338
|
+
await page.logInWithOptions(options: UniversalLoginOptions)
|
|
339
|
+
await page.logOut()
|
|
340
|
+
|
|
341
|
+
// Navigation — always use subject.goTo(), not page.goto() directly
|
|
342
|
+
await subject.goTo()
|
|
343
|
+
|
|
344
|
+
// Deep link navigation
|
|
345
|
+
await page.goToDeepLink('subject=employee/subjectVariant=editable_1')
|
|
346
|
+
|
|
347
|
+
// User simulation (for multi-user testing)
|
|
348
|
+
await page.simulateUser('another.user@example.com')
|
|
349
|
+
await page.getSimulatedUser() // → string
|
|
350
|
+
await page.stopSimulation()
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## Waiting and timing helpers
|
|
356
|
+
|
|
357
|
+
**Never use `page.waitForTimeout()`.** The Thinkwise application handles timing through these:
|
|
358
|
+
|
|
359
|
+
```typescript
|
|
360
|
+
// Wait for all XHR requests to settle (used internally by goTo)
|
|
361
|
+
const tracker = new FlightTracker();
|
|
362
|
+
await tracker.waitToContinue();
|
|
363
|
+
await tracker.waitForNavigationToSettle(spaStartupTimeout?) // also waits for SPA startup
|
|
364
|
+
|
|
365
|
+
// Wait for a specific response URL before continuing
|
|
366
|
+
await page.waitEventHandler.waitForResponse('/my-endpoint');
|
|
367
|
+
await page.waitEventHandler.waitForCanContinue();
|
|
368
|
+
|
|
369
|
+
// Polling until condition is met (returns the value when truthy)
|
|
370
|
+
import { pollUntil } from '@thinkwise/testwise';
|
|
371
|
+
await pollUntil(async () => (await page.locator('.my-el').count()) > 0, { timeout: 10000 });
|
|
372
|
+
|
|
373
|
+
// Guard assertions — throw with clear message instead of cryptic errors
|
|
374
|
+
import { ensure, ensureEqual } from '@thinkwise/testwise';
|
|
375
|
+
ensure(someValue != null, 'Expected someValue to be defined');
|
|
376
|
+
ensureEqual(actualStatus, 'Active', 'status');
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
---
|
|
380
|
+
|
|
381
|
+
## Assertions
|
|
382
|
+
|
|
383
|
+
Use standard Playwright `expect` — it's re-exported from `@thinkwise/testwise`:
|
|
384
|
+
|
|
385
|
+
```typescript
|
|
386
|
+
import { expect, test } from '@thinkwise/testwise';
|
|
387
|
+
|
|
388
|
+
await expect(subject.grid1.getCellByExactValue('John')).toBeVisible();
|
|
389
|
+
await expect(subject.actionBarXXXX.getSaveButton()).toBeEnabled();
|
|
390
|
+
await expect(subject.form1.firstNameField).toHaveValue('John');
|
|
391
|
+
await expect(page.getByText('mandatory field')).toBeVisible();
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## Common test patterns
|
|
397
|
+
|
|
398
|
+
### Add a record and verify it appears in the grid
|
|
399
|
+
```typescript
|
|
400
|
+
const subject = await page.subject.EmployeeEditable1Main;
|
|
401
|
+
await subject.goTo();
|
|
402
|
+
await subject.actionBarVXE6V0YT.getAddButton().click();
|
|
403
|
+
await subject.form1.firstNameField.fill('John');
|
|
404
|
+
await subject.form1.lastNameField.fill('Smith');
|
|
405
|
+
await subject.actionBarVXE6V0YT.getSaveButton().click();
|
|
406
|
+
await expect(subject.gridQT3UL7F8.firstNameColumn.getCellByExactValue('John')).toBeVisible();
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### Verify mandatory field validation
|
|
410
|
+
```typescript
|
|
411
|
+
await subject.actionBarVXE6V0YT.getAddButton().click();
|
|
412
|
+
await subject.actionBarVXE6V0YT.getSaveButton().click();
|
|
413
|
+
await expect(page.getByText('mandatory')).toBeVisible();
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Cancel with unsaved changes — handle popup
|
|
417
|
+
```typescript
|
|
418
|
+
await subject.actionBarVXE6V0YT.getAddButton().click();
|
|
419
|
+
await subject.form1.firstNameField.fill('test');
|
|
420
|
+
await subject.actionBarVXE6V0YT.getCancelButton().click();
|
|
421
|
+
await page.components.popUp.getActionButtonByText('yes').click(); // confirm discard
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
### Filter a grid
|
|
425
|
+
```typescript
|
|
426
|
+
await subject.actionBarVXE6V0YT.getFilterButton().click();
|
|
427
|
+
await subject.filterForm1.firstNameField.fill('John');
|
|
428
|
+
// grid auto-filters or press Enter depending on configuration
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### Open a detail tab
|
|
432
|
+
```typescript
|
|
433
|
+
const mainSubject = await page.subject.EmployeeMain;
|
|
434
|
+
await mainSubject.goTo();
|
|
435
|
+
await mainSubject.gridQT3UL7F8.getRowByIndex(0).click();
|
|
436
|
+
|
|
437
|
+
const detailSubject = await page.subject.EmployeeDetail;
|
|
438
|
+
await expect(detailSubject.form1.firstNameField).toBeVisible();
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
---
|
|
442
|
+
|
|
443
|
+
## What NOT to do
|
|
444
|
+
|
|
445
|
+
- ❌ `import { test } from '@playwright/test'` — always use `@thinkwise/testwise`
|
|
446
|
+
- ❌ `page.locator('[data-testid="..."]')` for interactions a Testwise component wraps
|
|
447
|
+
- ❌ Guess class names — call `list_artifacts` first
|
|
448
|
+
- ❌ Guess property names — call `get_components` first
|
|
449
|
+
- ❌ Guess field names — call `get_screen_interface` first
|
|
450
|
+
- ❌ `page.waitForTimeout()` — use Testwise timing helpers
|
|
451
|
+
- ❌ Drive the browser via any external MCP tool — only `run_tests` is safe
|
|
452
|
+
- ❌ Write raw `page.fill()` / `page.click()` when a typed component accessor exists
|
|
453
|
+
- ❌ Hardcode component property names with hash suffixes — always look them up
|
package/tsconfig.json
CHANGED
|
@@ -5,15 +5,19 @@
|
|
|
5
5
|
"moduleResolution": "nodenext",
|
|
6
6
|
"esModuleInterop": true,
|
|
7
7
|
"allowSyntheticDefaultImports": true,
|
|
8
|
+
"rootDir": ".",
|
|
8
9
|
"outDir": "dist",
|
|
9
10
|
"declaration": true,
|
|
10
11
|
"sourceMap": true,
|
|
11
12
|
"resolveJsonModule": true,
|
|
12
13
|
"skipLibCheck": true,
|
|
13
|
-
"strict": true
|
|
14
|
+
"strict": true,
|
|
15
|
+
"paths": {
|
|
16
|
+
"@thinkwise/testwise/helpers/SubjectNavigator": ["./helpers/SubjectNavigator.ts"]
|
|
17
|
+
}
|
|
14
18
|
},
|
|
15
19
|
"include": [
|
|
16
20
|
"**/*.ts"
|
|
17
21
|
],
|
|
18
|
-
"exclude": ["dist", "node_modules", "test-artifacts-temp", "templates
|
|
22
|
+
"exclude": ["dist", "node_modules", "test-artifacts-temp", "templates", "tests", "vitest.config.ts"]
|
|
19
23
|
}
|
package/types/Components.ts
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enumerates every Thinkwise UI component that the artifact pipeline can
|
|
3
|
+
* generate references to inside subject classes.
|
|
4
|
+
*
|
|
5
|
+
* Components are split into two groups:
|
|
6
|
+
*
|
|
7
|
+
* - **`SubjectAgnosticComponents`** (`coreComponents` array) — components that
|
|
8
|
+
* are identical across all subjects and don't need subject-specific typing.
|
|
9
|
+
* Examples: `ActionBar`, `Tab`, `FilterForm`, `TreeView`.
|
|
10
|
+
*
|
|
11
|
+
* - **`SubjectComponents`** (`subjectComponents` array) — `Form` and `Grid`,
|
|
12
|
+
* which get a fully-typed generated `Components/` subfolder with field/column
|
|
13
|
+
* accessors specific to that subject.
|
|
14
|
+
*
|
|
15
|
+
* The `SelectorBuilder` in the artifact-builder uses these lists to decide
|
|
16
|
+
* which locator strategy to apply when generating subject class properties.
|
|
17
|
+
*/
|
|
1
18
|
export type SubjectAgnosticComponents =
|
|
2
19
|
| 'Chart'
|
|
3
20
|
| 'PivotGridFieldList'
|
|
@@ -7,7 +24,6 @@ export type SubjectAgnosticComponents =
|
|
|
7
24
|
| 'CustomActionBar'
|
|
8
25
|
| 'DetailTabPage'
|
|
9
26
|
| 'Tab'
|
|
10
|
-
| 'Tab'
|
|
11
27
|
| 'TaskTiles'
|
|
12
28
|
| 'FilterForm'
|
|
13
29
|
| 'PrefilterList'
|
|
@@ -30,7 +46,6 @@ export const coreComponents: SubjectAgnosticComponents[] = [
|
|
|
30
46
|
'Tab',
|
|
31
47
|
'DetailTabPage',
|
|
32
48
|
'TaskBar',
|
|
33
|
-
'Tab',
|
|
34
49
|
'Cardlist',
|
|
35
50
|
'FilterForm',
|
|
36
51
|
'TaskTiles',
|
package/types/PollTypes.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for `pollUntil()` — controls how the polling loop behaves.
|
|
3
|
+
*
|
|
4
|
+
* All fields are optional; sensible defaults are used if omitted:
|
|
5
|
+
* - `timeout`: 10 000 ms
|
|
6
|
+
* - `interval`: 200 ms
|
|
7
|
+
* - `predicate`: truthy check on the returned value
|
|
8
|
+
*/
|
|
1
9
|
export type PollOptions<T = unknown> = {
|
|
2
10
|
timeout?: number; // ms (default 10_000)
|
|
3
11
|
interval?: number; // ms (default 200)
|
package/types/Test.ts
CHANGED
|
@@ -6,4 +6,22 @@ import type {
|
|
|
6
6
|
TestType
|
|
7
7
|
} from '@playwright/test';
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Convenience alias for the fully-typed Playwright `TestType` that includes
|
|
11
|
+
* all built-in test arguments and options (both per-test and per-worker).
|
|
12
|
+
*
|
|
13
|
+
* Used throughout the library instead of the verbose `TestType<...>` generic
|
|
14
|
+
* to keep constructor signatures readable. Every page-extension and
|
|
15
|
+
* page-override receives and returns a `Test` so they can chain
|
|
16
|
+
* `test.extend()` calls cleanly.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* import type { Test } from '../types/Test.js';
|
|
20
|
+
*
|
|
21
|
+
* export class MyExtension {
|
|
22
|
+
* constructor(test: Test) {
|
|
23
|
+
* this._test = test.extend({ ... });
|
|
24
|
+
* }
|
|
25
|
+
* }
|
|
26
|
+
*/
|
|
9
27
|
export type Test = TestType<PlaywrightTestArgs & PlaywrightTestOptions, PlaywrightWorkerArgs & PlaywrightWorkerOptions>;
|
package/types/Universal.ts
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration and login option shapes used by `LoginHelper` and the
|
|
3
|
+
* `LoginFeatures` page extension.
|
|
4
|
+
*
|
|
5
|
+
* - `UniversalConfigOptions` — feature flags and settings applied when
|
|
6
|
+
* configuring the Thinkwise application during login.
|
|
7
|
+
* - `UniversalLoginOptions` — full set of overrides for a single login call
|
|
8
|
+
* (credentials, application ID, config options, etc.).
|
|
9
|
+
*
|
|
10
|
+
* These types are used internally; you typically only interact with them
|
|
11
|
+
* via `page.logInWithOptions(options)`.
|
|
12
|
+
*/
|
|
1
13
|
export type UniversalConfigOptions = {
|
|
2
14
|
barcodeScannerSymbologies?: string;
|
|
3
15
|
cortexEnabledSymbologies?: string[];
|
package/types/index.ts
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"IStoredTestResults.js","sourceRoot":"","sources":["../../interfaces/IStoredTestResults.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SubjectPageBase.js","sourceRoot":"","sources":["../../../templates/test-artifacts/SubjectPageBase.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,eAAe;IAG1B,YAAY,WAAoB;QAC9B,IAAI,CAAC,OAAO,GAAG,WAAW,CAAC;IAC7B,CAAC;CACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../templates/test-artifacts/screens/index.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../templates/test-artifacts/subjects/index.ts"],"names":[],"mappings":""}
|