From 1bdda95456c1af5be8284c493d0c9f89f8e2dd4a Mon Sep 17 00:00:00 2001 From: ivakoleva Date: Wed, 1 Mar 2023 09:51:32 +0200 Subject: [PATCH] versatile-data-kit: pre-commit hook for (S)CSS/JS/TS/HTML formatting (#1684) We need a formatting pre-commit hook, to cover the new tech stack added with the Frontend component. Adding and configured a pre-commit hook. Testing done: tested locally; ci/cd --------- Signed-off-by: ivakoleva Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 17 +- .../gui/e2e/integration/app/app.spec.js | 21 +- .../getting-started/getting-started.spec.js | 139 +- .../lib/explore/data-job-details.spec.js | 327 +- .../lib/explore/data-job-executions.spec.js | 164 +- .../integration/lib/explore/data-jobs.spec.js | 546 +- .../lib/manage/data-job-details.int.spec.js | 423 +- .../manage/data-job-executions.int.spec.js | 1120 +- .../lib/manage/data-jobs.int.spec.js | 967 +- .../data-pipelines/gui/e2e/plugins/index.js | 24 +- .../support/application/data-job-base.po.js | 57 +- .../application/data-job-details-base.po.js | 32 +- .../support/application/data-jobs-base.po.js | 92 +- .../application/data-pipelines-base.po.js | 31 +- .../gui/e2e/support/commands.js | 425 +- .../e2e/support/helpers/commands.helpers.js | 763 +- .../data-pipelines/gui/e2e/support/index.js | 12 +- .../gui/e2e/support/pages/app/app.po.js | 6 +- .../data-jobs-health-panel-component.po.js | 56 +- .../app/getting-started/getting-started.po.js | 8 +- .../app/lib/explore/data-job-details.po.js | 4 +- .../pages/app/lib/explore/data-jobs.po.js | 58 +- .../app/lib/manage/data-job-details.po.js | 115 +- .../app/lib/manage/data-job-executions.po.js | 211 +- .../pages/app/lib/manage/data-jobs.po.js | 144 +- .../gui/projects/data-pipelines/karma.conf.js | 62 +- .../_data-jobs-base-grid.component.scss | 196 +- .../data-jobs-base-grid.component.ts | 316 +- .../data-job/data-job-page.component.html | 302 +- .../data-job/data-job-page.component.scss | 144 +- .../data-job/data-job-page.component.spec.ts | 141 +- .../data-job/data-job-page.component.ts | 389 +- .../data-job-details-page.component.html | 782 +- .../data-job-details-page.component.scss | 159 +- .../data-job-details-page.component.spec.ts | 185 +- .../data-job-details-page.component.ts | 180 +- ...ob-deployment-details-modal.component.html | 43 +- ...ob-deployment-details-modal.component.scss | 11 +- ...-job-deployment-details-modal.component.ts | 29 +- ...job-execution-status-filter.component.html | 14 +- ...a-job-execution-status-filter.component.ts | 13 +- .../data-job-execution-status.component.html | 30 +- .../data-job-execution-status.component.scss | 10 +- .../data-job-execution-status.component.ts | 84 +- ...a-job-execution-type-filter.component.html | 16 +- ...ata-job-execution-type-filter.component.ts | 10 +- .../data-job-execution-type.component.html | 17 +- .../data-job-execution-type.component.ts | 10 +- .../execution-duration-comparator.spec.ts | 16 +- .../execution-duration-comparator.ts | 4 +- .../data-job-executions-grid.component.html | 163 +- .../data-job-executions-grid.component.scss | 6 +- .../data-job-executions-grid.component.ts | 15 +- .../data-job-executions-page.component.html | 44 +- .../data-job-executions-page.component.scss | 42 +- .../data-job-executions-page.component.ts | 150 +- .../execution-duration-chart.component.html | 20 +- .../execution-duration-chart.component.scss | 26 +- .../execution-duration-chart.component.ts | 306 +- .../execution-status-chart.component.html | 12 +- .../execution-status-chart.component.scss | 22 +- .../execution-status-chart.component.ts | 119 +- .../model/data-job-execution.spec.ts | 29 +- .../executions/model/data-job-execution.ts | 34 +- .../time-period-filter.component.html | 197 +- .../time-period-filter.component.scss | 649 +- .../time-period-filter.component.ts | 109 +- .../data-jobs-explore-grid.component.html | 532 +- .../data-jobs-explore-grid.component.scss | 6 +- .../data-jobs-explore-grid.component.spec.ts | 186 +- .../grid/data-jobs-explore-grid.component.ts | 36 +- .../data-jobs-explore-page.component.html | 7 +- .../data-jobs-explore-page.component.spec.ts | 2 +- .../data-jobs-explore-page.component.ts | 5 +- .../grid/data-jobs-manage-grid.component.html | 607 +- .../grid/data-jobs-manage-grid.component.scss | 10 +- .../data-jobs-manage-grid.component.spec.ts | 176 +- .../grid/data-jobs-manage-grid.component.ts | 153 +- .../data-jobs-manage-page.component.html | 7 +- .../data-jobs-manage-page.component.spec.ts | 2 +- .../data-jobs-manage-page.component.ts | 5 +- ...data-jobs-executions-widget.component.html | 72 +- ...data-jobs-executions-widget.component.scss | 84 +- .../data-jobs-executions-widget.component.ts | 24 +- .../data-jobs-failed-widget.component.html | 41 +- .../data-jobs-failed-widget.component.scss | 74 +- .../data-jobs-failed-widget.component.ts | 31 +- .../data-jobs-health-panel.component.html | 106 +- .../data-jobs-health-panel.component.scss | 469 +- .../data-jobs-health-panel.component.ts | 90 +- .../data-jobs-widget-one.component.html | 177 +- .../data-jobs-widget-one.component.scss | 450 +- .../data-jobs-widget-one.component.spec.ts | 69 +- .../widgets/data-jobs-widget-one.component.ts | 81 +- .../src/lib/components/widgets/variables.scss | 6 +- ...dget-execution-status-gauge.component.html | 35 +- ...dget-execution-status-gauge.component.scss | 776 +- ...widget-execution-status-gauge.component.ts | 12 +- .../src/lib/components/widgets/widget.scss | 23 +- .../src/lib/data-pipelines.module.ts | 38 +- .../src/lib/model/constants.model.ts | 4 +- .../src/lib/model/data-job-base.model.ts | 10 +- .../lib/model/data-job-deployments.model.ts | 5 +- .../lib/model/data-job-executions.model.ts | 8 +- .../src/lib/model/data-job.model.ts | 8 +- .../src/lib/model/grid-config.model.ts | 2 +- .../src/lib/model/route.model.ts | 10 +- .../src/lib/model/toast-definitions.model.ts | 2 +- .../data-jobs-base.api.service.spec.ts | 181 +- .../services/data-jobs-base.api.service.ts | 87 +- .../data-jobs-public.api.service.spec.ts | 94 +- .../services/data-jobs-public.api.service.ts | 97 +- .../services/data-jobs.api.service.spec.ts | 200 +- .../src/lib/services/data-jobs.api.service.ts | 184 +- .../lib/services/data-jobs.service.spec.ts | 143 +- .../src/lib/services/data-jobs.service.ts | 29 +- .../confirmation-dialog-modal.component.html | 39 +- .../confirmation-dialog-modal.component.scss | 21 +- ...onfirmation-dialog-modal.component.spec.ts | 7 +- .../confirmation-dialog-modal.component.ts | 3 +- .../column-filter.component.html | 33 +- .../column-filter.component.scss | 11 +- .../column-filter.component.spec.ts | 21 +- .../column-filter/column-filter.component.ts | 18 +- .../grid-action/grid-action.component.html | 114 +- .../grid-action/grid-action.component.scss | 114 +- .../grid-action/grid-action.component.spec.ts | 2 +- .../grid-action/grid-action.component.ts | 32 +- .../delete-modal/delete-modal.component.html | 37 +- .../delete-modal.component.spec.ts | 2 +- .../delete-modal/delete-modal.component.ts | 3 +- .../empty-state/empty-state.component.html | 8 +- .../empty-state/empty-state.component.scss | 27 +- .../empty-state/empty-state.component.spec.ts | 12 +- .../empty-state/empty-state.component.ts | 25 +- .../executions-timeline.component.html | 176 +- .../executions-timeline.component.scss | 56 +- .../executions-timeline.component.spec.ts | 37 +- .../executions-timeline.component.ts | 30 +- .../components/modal/modal.component.ts | 6 +- .../quick-filters.component.html | 43 +- .../quick-filters.component.scss | 44 +- .../quick-filters.component.spec.ts | 5 +- .../quick-filters/quick-filters.component.ts | 39 +- .../status-cell/status-cell.component.html | 60 +- .../status-cell/status-cell.component.spec.ts | 12 +- .../status-cell/status-cell.component.ts | 2 +- .../status-panel/status-panel.component.html | 36 +- .../status-panel.component.spec.ts | 8 +- .../status-panel/status-panel.component.ts | 2 +- .../widget-value/widget-value.component.html | 15 +- .../widget-value.component.spec.ts | 5 +- .../widget-value/widget-value.component.ts | 2 +- .../directives/attribute.directive.spec.ts | 17 +- .../shared/directives/attribute.directive.ts | 69 +- .../lib/shared/model/modal-options.spec.ts | 8 +- .../pipes/contacts-present.pipe.spec.ts | 39 +- .../lib/shared/pipes/contacts-present.pipe.ts | 24 +- .../pipes/execution-success-rate.pipe.spec.ts | 4 +- .../pipes/execution-success-rate.pipe.ts | 13 +- .../lib/shared/pipes/extract-contacts.pipe.ts | 4 +- .../pipes/extract-job-status.pipe.spec.ts | 4 +- .../shared/pipes/extract-job-status.pipe.ts | 2 +- .../shared/pipes/format-delta.pipe.spec.ts | 10 +- .../src/lib/shared/pipes/format-delta.pipe.ts | 25 +- .../lib/shared/pipes/format-duration.pipe.ts | 6 +- .../shared/pipes/format-schedule.pipe.spec.ts | 112 +- .../lib/shared/pipes/format-schedule.pipe.ts | 33 +- .../lib/shared/pipes/parse-epoch.pipe.spec.ts | 4 +- .../src/lib/shared/pipes/parse-epoch.pipe.ts | 2 +- .../shared/pipes/parse-next-run.pipe.spec.ts | 46 +- .../lib/shared/pipes/parse-next-run.pipe.ts | 2 +- .../src/lib/shared/utils/cron.util.spec.ts | 4 +- .../src/lib/shared/utils/cron.util.ts | 2 +- .../lib/shared/utils/data-job.util.spec.ts | 81 +- .../src/lib/shared/utils/data-job.util.ts | 80 +- .../src/lib/shared/utils/date.util.spec.ts | 36 +- .../src/lib/shared/utils/date.util.ts | 10 +- .../src/lib/shared/utils/error.util.ts | 5 +- .../src/lib/shared/utils/string.util.spec.ts | 16 +- .../lib/state/actions/data-jobs.actions.ts | 3 +- .../state/effects/data-jobs.effects.spec.ts | 915 +- .../lib/state/effects/data-jobs.effects.ts | 331 +- .../src/lib/state/tasks/data-job.tasks.ts | 6 +- .../gui/projects/data-pipelines/src/test.ts | 13 +- .../gui/projects/ui/karma.conf.js | 60 +- .../projects/ui/src/app/app.component.html | 53 +- .../projects/ui/src/app/app.component.scss | 26 +- .../projects/ui/src/app/app.component.spec.ts | 24 +- .../gui/projects/ui/src/app/app.component.ts | 60 +- .../gui/projects/ui/src/app/app.module.ts | 33 +- .../gui/projects/ui/src/app/app.routing.ts | 57 +- .../gui/projects/ui/src/app/auth.ts | 7 +- .../getting-started.component.html | 51 +- .../getting-started.component.spec.ts | 5 +- .../getting-started.component.ts | 2 +- .../projects/ui/src/app/http.interceptor.ts | 45 +- .../projects/ui/src/assets/css/clr-ui.min.css | 17599 +++++++++++++++- .../ui/src/environments/environment.prod.ts | 2 +- .../ui/src/environments/environment.ts | 4 +- .../gui/projects/ui/src/index.html | 28 +- .../gui/projects/ui/src/main.ts | 2 +- .../gui/projects/ui/src/styles.scss | 142 +- .../gui/projects/ui/src/test.ts | 13 +- .../projects/documentation-ui/karma.conf.js | 124 +- .../src/app/app-routing.module.ts | 29 +- .../src/app/app.component.html | 103 +- .../src/app/app.component.scss | 48 +- .../src/app/app.component.spec.ts | 34 +- .../documentation-ui/src/app/app.component.ts | 42 +- .../documentation-ui/src/app/app.module.ts | 80 +- .../projects/documentation-ui/src/app/auth.ts | 34 +- .../src/app/core/core.component.html | 7 +- .../src/app/core/core.component.scss | 23 +- .../src/app/core/core.component.spec.ts | 30 +- .../src/app/core/core.component.ts | 9 +- .../src/app/core/core.module.ts | 15 +- .../src/app/http.interceptor.ts | 108 +- .../src/environments/environment.prod.ts | 2 +- .../src/environments/environment.ts | 4 +- .../projects/documentation-ui/src/index.html | 24 +- .../gui/projects/documentation-ui/src/main.ts | 6 +- .../projects/documentation-ui/src/styles.scss | 210 +- .../gui/projects/documentation-ui/src/test.ts | 27 +- .../gui/projects/shared/karma.conf.js | 121 +- .../shared/src/lib/common/http/index.ts | 2 - .../shared/src/lib/common/http/public-api.ts | 2 - .../src/lib/common/http/request/index.ts | 2 - .../common/http/request/request.model.spec.ts | 801 +- .../lib/common/http/request/request.model.ts | 275 +- .../projects/shared/src/lib/common/index.ts | 2 - .../common/interfaces/comparable.interface.ts | 98 +- .../lib/common/interfaces/copy.interface.ts | 12 +- .../common/interfaces/expression.interface.ts | 18 +- .../shared/src/lib/common/interfaces/index.ts | 2 - .../common/interfaces/literal.interface.ts | 36 +- .../common/interfaces/predicate.interface.ts | 23 +- .../src/lib/common/interfaces/public-api.ts | 2 - .../common/interfaces/replacer.interface.ts | 6 +- .../interfaces/serializable.interface.ts | 22 +- .../shared/src/lib/common/object/index.ts | 2 - .../src/lib/common/object/model/index.ts | 2 - .../object/model/taurus-object.model.spec.ts | 317 +- .../object/model/taurus-object.model.ts | 141 +- .../src/lib/common/object/public-api.ts | 2 - .../comparable/comparable.impl.spec.ts | 558 +- .../predicate/comparable/comparable.impl.ts | 196 +- .../lib/common/predicate/comparable/index.ts | 2 - .../predicates-comparable.impl.spec.ts | 659 +- .../comparable/predicates-comparable.impl.ts | 204 +- .../predicate/compound/and.predicate.spec.ts | 245 +- .../predicate/compound/and.predicate.ts | 41 +- .../compound/base-compound.predicate.spec.ts | 33 +- .../compound/base-compound.predicate.ts | 72 +- .../lib/common/predicate/compound/index.ts | 2 - .../predicate/compound/or.predicate.spec.ts | 245 +- .../common/predicate/compound/or.predicate.ts | 41 +- .../shared/src/lib/common/predicate/index.ts | 2 - .../src/lib/common/predicate/public-api.ts | 2 - .../simple/base-simple.predicate.spec.ts | 33 +- .../predicate/simple/base-simple.predicate.ts | 46 +- .../predicate/simple/equal.predicate.spec.ts | 136 +- .../predicate/simple/equal.predicate.ts | 42 +- .../src/lib/common/predicate/simple/index.ts | 2 - .../shared/src/lib/common/public-api.ts | 2 - .../shared/src/lib/common/route/index.ts | 2 - .../shared/src/lib/common/route/public-api.ts | 2 - .../src/lib/common/route/route.model.ts | 143 +- .../shared/src/lib/common/tasks/index.ts | 2 - .../shared/src/lib/common/tasks/public-api.ts | 2 - .../src/lib/common/tasks/task.model.spec.ts | 97 +- .../shared/src/lib/common/tasks/task.model.ts | 36 +- .../shared/src/lib/commons/css/colors.scss | 14 +- .../src/lib/commons/css/screen-sizes.scss | 24 +- .../shared/src/lib/commons/css/utils.scss | 15 +- .../projects/shared/src/lib/commons/index.ts | 2 - .../ngx-components/animation-constants.ts | 6 +- .../copy-to-clipboard-button.component.html | 84 +- .../copy-to-clipboard-button.component.scss | 130 +- ...copy-to-clipboard-button.component.spec.ts | 163 +- .../copy-to-clipboard-button.component.ts | 228 +- .../copy-to-clipboard-button.l10n.ts | 72 +- .../copy-to-clipboard-button/index.ts | 8 +- .../copy-to-clipboard-button/public-api.ts | 2 - .../empty-state-placeholder.component.html | 15 +- .../empty-state-placeholder.component.scss | 62 +- .../empty-state-placeholder.component.ts | 16 +- .../empty-state-placeholder.module.ts | 27 +- .../empty-state-placeholder/index.ts | 6 +- .../empty-state-placeholder/public-api.ts | 2 - .../form-section-container.component.html | 92 +- .../form-section-container.component.scss | 12 +- .../form-section-container.component.spec.ts | 378 +- .../form-section-container.component.ts | 328 +- .../form-section-container/index.ts | 8 +- .../form-section-container/public-api.ts | 2 - .../form-section/form-section.component.html | 25 +- .../form-section/form-section.component.scss | 53 +- .../form-section.component.spec.ts | 118 +- .../form-section/form-section.component.ts | 99 +- .../ngx-components/form-section/index.ts | 10 +- .../ngx-components/form-section/public-api.ts | 3 - .../src/lib/commons/ngx-components/index.ts | 17 +- .../lib/commons/ngx-components/public-api.ts | 2 - .../commons/ngx-components/search/index.ts | 2 +- .../ngx-components/search/public-api.ts | 2 - .../search/search.component.html | 96 +- .../search/search.component.scss | 140 +- .../search/search.component.spec.ts | 421 +- .../ngx-components/search/search.component.ts | 261 +- .../ngx-components/search/search.module.ts | 25 +- .../lib/commons/ngx-components/toast/index.ts | 17 +- .../ngx-components/toast/public-api.ts | 2 - .../toast/toast-container.component.html | 2 +- .../toast/toast-container.component.scss | 40 +- .../toast/toast-container.component.ts | 59 +- .../ngx-components/toast/toast.component.html | 190 +- .../ngx-components/toast/toast.component.scss | 469 +- .../ngx-components/toast/toast.component.ts | 632 +- .../ngx-components/toast/toast.l10n.ts | 144 +- .../ngx-components/toast/toast.model.ts | 8 +- .../vdk-ngx-components.module.ts | 160 +- .../shared/src/lib/commons/ngx-utils/index.ts | 2 +- .../src/lib/commons/ngx-utils/public-api.ts | 2 - .../simple-translate-service/index.ts | 6 +- .../simple-translate-service/public-api.ts | 2 - .../simple-translate.module.ts | 30 +- .../simple-translate.pipe.ts | 12 +- .../simple-translate.service.spec.ts | 96 +- .../simple-translate.service.ts | 167 +- .../src/lib/core/component/base/index.ts | 2 - .../core/component/base/interfaces/index.ts | 2 - ...rus-component-lifecycle-hooks.interface.ts | 141 +- .../base/taurus-base.component.spec.ts | 1192 +- .../component/base/taurus-base.component.ts | 637 +- .../shared/src/lib/core/component/index.ts | 2 - .../model/component-model.comparable.spec.ts | 465 +- .../model/component-model.comparable.ts | 133 +- .../model/component.model.interface.ts | 329 +- .../component/model/component.model.spec.ts | 923 +- .../core/component/model/component.model.ts | 464 +- .../src/lib/core/component/model/index.ts | 2 - .../model/state/component-state.model.spec.ts | 598 +- .../model/state/component-state.model.ts | 824 +- .../model/state/component-status.model.ts | 9 +- .../state/components-state.model.spec.ts | 648 +- .../model/state/components-state.model.ts | 560 +- .../lib/core/component/model/state/index.ts | 2 - .../src/lib/core/component/public-api.ts | 2 - .../services/component.service.spec.ts | 1652 +- .../component/services/component.service.ts | 770 +- .../src/lib/core/component/services/index.ts | 2 - .../state/actions/component.actions.spec.ts | 570 +- .../state/actions/component.actions.ts | 152 +- .../lib/core/component/state/actions/index.ts | 2 - .../src/lib/core/component/state/index.ts | 2 - .../operators/component-rx.operators.spec.ts | 436 +- .../state/operators/component-rx.operators.ts | 110 +- .../core/component/state/operators/index.ts | 2 - .../state/reducers/component.reducer.spec.ts | 842 +- .../state/reducers/component.reducer.ts | 277 +- .../core/component/state/reducers/index.ts | 2 - .../gui/projects/shared/src/lib/core/index.ts | 2 - .../shared/src/lib/core/navigation/index.ts | 2 - .../src/lib/core/navigation/public-api.ts | 2 - .../src/lib/core/navigation/services/index.ts | 2 - .../services/navigation.service.spec.ts | 870 +- .../navigation/services/navigation.service.ts | 699 +- .../core/ngrx/actions/base.actions.spec.ts | 134 +- .../src/lib/core/ngrx/actions/base.actions.ts | 99 +- .../shared/src/lib/core/ngrx/actions/index.ts | 2 - .../shared/src/lib/core/ngrx/config/index.ts | 2 - .../ngrx/config/ngrx-config.model.spec.ts | 43 +- .../lib/core/ngrx/config/ngrx-config.model.ts | 29 +- .../shared/src/lib/core/ngrx/effects/index.ts | 2 - .../effects/root-effects.registry.spec.ts | 10 +- .../ngrx/effects/root-effects.registry.ts | 6 +- .../src/lib/core/ngrx/helper-modules/index.ts | 2 - .../taurus-shared-ngrx-dev.module.ts | 67 +- .../taurus-shared-ngrx-prod.module.ts | 42 +- .../shared/src/lib/core/ngrx/index.ts | 2 - .../shared/src/lib/core/ngrx/public-api.ts | 2 - .../src/lib/core/ngrx/reducers/index.ts | 2 - .../shared-root-reducers.registry.spec.ts | 16 +- .../reducers/shared-root-reducers.registry.ts | 6 +- .../shared/src/lib/core/ngrx/state/index.ts | 2 - .../lib/core/ngrx/state/store-state.model.ts | 6 +- .../core/ngrx/taurus-shared-ngrx.module.ts | 135 +- .../shared/src/lib/core/public-api.ts | 2 - .../src/lib/core/router/factory/index.ts | 2 - .../factory/route-state.factory.spec.ts | 85 +- .../router/factory/route-state.factory.ts | 76 +- .../shared/src/lib/core/router/index.ts | 2 - .../lib/core/router/integration/ngrx/index.ts | 2 - .../ngrx/router-serializer.service.spec.ts | 193 +- .../ngrx/router-serializer.service.ts | 48 +- .../shared/src/lib/core/router/model/index.ts | 2 - .../lib/core/router/model/route.model.spec.ts | 1555 +- .../src/lib/core/router/model/route.model.ts | 807 +- .../shared/src/lib/core/router/public-api.ts | 2 - .../src/lib/core/router/services/index.ts | 2 - .../router/services/router.service.spec.ts | 353 +- .../core/router/services/router.service.ts | 125 +- .../lib/core/router/state/actions/index.ts | 2 - .../state/actions/router.actions.spec.ts | 337 +- .../router/state/actions/router.actions.ts | 102 +- .../lib/core/router/state/effects/index.ts | 2 - .../state/effects/router.effects.spec.ts | 251 +- .../router/state/effects/router.effects.ts | 147 +- .../lib/core/router/state/reducers/index.ts | 2 - .../state/reducers/router.reducer.spec.ts | 62 +- .../router/state/reducers/router.reducer.ts | 56 +- .../event-handler-class.decorator.ts | 154 +- .../decorator/event-handler.decorator.spec.ts | 111 +- .../decorator/event-handler.decorator.ts | 71 +- .../lib/core/system-events/decorator/index.ts | 2 - .../models/event-decorator-helper.ts | 5 +- .../system-events/decorator/models/index.ts | 2 - .../dispatcher/event.dispatcher.spec.ts | 320 +- .../dispatcher/event.dispatcher.ts | 266 +- .../core/system-events/dispatcher/index.ts | 2 - .../models/event-dispatcher.model.ts | 47 +- .../system-events/dispatcher/models/index.ts | 2 - .../registry/event-handler.registry.spec.ts | 522 +- .../registry/event-handler.registry.ts | 521 +- .../dispatcher/registry/index.ts | 2 - .../src/lib/core/system-events/event/index.ts | 2 - .../models/event-filter.expression.spec.ts | 277 +- .../event/models/event-filter.expression.ts | 81 +- .../event/models/event-helper.ts | 2 - .../system-events/event/models/event.codes.ts | 2 - .../event/models/event.comparable.spec.ts | 280 +- .../event/models/event.comparable.ts | 72 +- .../core/system-events/event/models/index.ts | 2 - .../src/lib/core/system-events/index.ts | 2 - .../src/lib/core/system-events/public-api.ts | 10 +- .../src/lib/core/taurus-shared-core.module.ts | 56 +- .../src/lib/core/url-state-manager/index.ts | 2 - .../lib/core/url-state-manager/public-api.ts | 2 - .../url-state-manager/url-state.manager.ts | 456 +- .../lib/features/error-handler/public-api.ts | 2 - .../service/error-handler.service.spec.ts | 953 +- .../service/error-handler.service.ts | 337 +- .../features/error-handler/service/index.ts | 2 - .../shared/src/lib/features/public-api.ts | 2 - .../features/taurus-shared-features.module.ts | 71 +- .../src/lib/features/toasts/model/index.ts | 2 - .../features/toasts/model/toast.interface.ts | 28 +- .../src/lib/features/toasts/public-api.ts | 2 - .../src/lib/features/toasts/service/index.ts | 2 - .../toasts/service/toast.service.spec.ts | 48 +- .../features/toasts/service/toast.service.ts | 28 +- .../src/lib/features/toasts/toasts.module.ts | 18 +- .../src/lib/features/toasts/widget/index.ts | 2 - .../toasts/widget/toasts.component.html | 47 +- .../toasts/widget/toasts.component.scss | 16 +- .../toasts/widget/toasts.component.spec.ts | 82 +- .../toasts/widget/toasts.component.ts | 282 +- .../shared/src/lib/unit-testing/index.ts | 2 - .../shared/src/lib/unit-testing/public-api.ts | 2 - .../src/lib/unit-testing/utils/index.ts | 2 - .../lib/unit-testing/utils/router-utils.ts | 220 +- .../lib/unit-testing/utils/unit-test-utils.ts | 22 +- .../collections/collections-util.spec.ts | 2009 +- .../lib/utils/collections/collections-util.ts | 911 +- .../shared/src/lib/utils/collections/index.ts | 2 - .../projects/shared/src/lib/utils/index.ts | 2 - .../shared/src/lib/utils/model/data-source.ts | 30 +- .../shared/src/lib/utils/model/index.ts | 2 - .../src/lib/utils/model/shorthand-types.ts | 32 +- .../shared/src/lib/utils/public-api.ts | 40 +- .../shared/src/lib/utils/url/index.ts | 2 - .../shared/src/lib/utils/url/url.util.spec.ts | 52 +- .../shared/src/lib/utils/url/url.util.ts | 26 +- .../gui/projects/shared/src/test.ts | 27 +- .../vdk-jupyterlab-extension/src/index.ts | 5 +- .../vdk-jupyterlab-extension/src/jobData.ts | 1 - .../src/serverRequests.ts | 2 +- .../vdk-jupyterlab-extension/src/utils.ts | 1 - .../src/vdkOptions/vdk_options.ts | 14 +- .../tests/vdk-jupyterlab-extension.spec.ts | 96 +- 481 files changed, 49124 insertions(+), 26006 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 716c0a44d9..f8caca2cef 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -139,15 +139,8 @@ repos: - --use-current-year - --license-filepath - NOTICE.txt -# License header create issues in helm chart yaml files -# https://github.com/helm/helm/issues/4409 -# - id: insert-license -# files: \.yml$ -# args: -# - --license-filepath -# - NOTICE.txt -# - id: insert-license -# files: \.yaml$ -# args: -# - --license-filepath -# - NOTICE.txt + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v2.7.1 + hooks: + - id: prettier + types_or: [scss, css, javascript, ts, html] diff --git a/projects/frontend/data-pipelines/gui/e2e/integration/app/app.spec.js b/projects/frontend/data-pipelines/gui/e2e/integration/app/app.spec.js index fa088eef37..00ea1a928a 100644 --- a/projects/frontend/data-pipelines/gui/e2e/integration/app/app.spec.js +++ b/projects/frontend/data-pipelines/gui/e2e/integration/app/app.spec.js @@ -5,14 +5,14 @@ /// -import { AppPage } from '../../support/pages/app/app.po'; +import { AppPage } from "../../support/pages/app/app.po"; -describe('App Page', { tags: ['@dataPipelines'] }, () => { +describe("App Page", { tags: ["@dataPipelines"] }, () => { before(() => { return AppPage.recordHarIfSupported() - .then(() => cy.clearLocalStorageSnapshot('app')) - .then(() => AppPage.login()) - .then(() => cy.saveLocalStorage('app')); + .then(() => cy.clearLocalStorageSnapshot("app")) + .then(() => AppPage.login()) + .then(() => cy.saveLocalStorage("app")); }); after(() => { @@ -20,19 +20,16 @@ describe('App Page', { tags: ['@dataPipelines'] }, () => { }); beforeEach(() => { - cy.restoreLocalStorage('app'); + cy.restoreLocalStorage("app"); }); - it('App Page - Main Title Component have text: Data Pipelines', () => { + it("App Page - Main Title Component have text: Data Pipelines", () => { AppPage.navigateTo(); const page = AppPage.getPage(); - page - .waitForInitialPageLoad(); + page.waitForInitialPageLoad(); - page - .getMainTitle() - .should('have.text', 'Data Pipelines'); + page.getMainTitle().should("have.text", "Data Pipelines"); }); }); diff --git a/projects/frontend/data-pipelines/gui/e2e/integration/app/getting-started/getting-started.spec.js b/projects/frontend/data-pipelines/gui/e2e/integration/app/getting-started/getting-started.spec.js index 6a3d354a5f..9b40e1e712 100644 --- a/projects/frontend/data-pipelines/gui/e2e/integration/app/getting-started/getting-started.spec.js +++ b/projects/frontend/data-pipelines/gui/e2e/integration/app/getting-started/getting-started.spec.js @@ -4,29 +4,32 @@ */ /// -import { DataPipelinesBasePO } from '../../../support/application/data-pipelines-base.po'; -import { GettingStartedPage } from '../../../support/pages/app/getting-started/getting-started.po'; -import { DataJobsHealthPanelComponentPO } from '../../../support/pages/app/getting-started/data-jobs-health-panel-component.po'; -import { DataJobManageDetailsPage } from '../../../support/pages/app/lib/manage/data-job-details.po'; -import { DataJobManageExecutionsPage } from '../../../support/pages/app/lib/manage/data-job-executions.po'; -import { applyGlobalEnvSettings } from '../../../support/helpers/commands.helpers'; - -describe('Getting Started Page', { tags: ['@dataPipelines'] }, () => { +import { DataPipelinesBasePO } from "../../../support/application/data-pipelines-base.po"; +import { GettingStartedPage } from "../../../support/pages/app/getting-started/getting-started.po"; +import { DataJobsHealthPanelComponentPO } from "../../../support/pages/app/getting-started/data-jobs-health-panel-component.po"; +import { DataJobManageDetailsPage } from "../../../support/pages/app/lib/manage/data-job-details.po"; +import { DataJobManageExecutionsPage } from "../../../support/pages/app/lib/manage/data-job-executions.po"; +import { applyGlobalEnvSettings } from "../../../support/helpers/commands.helpers"; + +describe("Getting Started Page", { tags: ["@dataPipelines"] }, () => { let testJob; before(() => { return DataPipelinesBasePO.recordHarIfSupported() - .then(() => cy.clearLocalStorageSnapshot('getting-started')) - .then(() => DataPipelinesBasePO.login()) - .then(() => cy.saveLocalStorage('getting-started')) - .then(() => cy.prepareLongLivedFailingTestJob()) - .then(() => cy.createExecutionsLongLivedFailingTestJob()) - .then(() => cy.fixture('e2e-cy-dp-failing.job.json')) - .then((failingTestJob) => { - testJob = applyGlobalEnvSettings(failingTestJob); - - return cy.wrap({ context: 'getting-started.spec::before()', action: 'continue' }); - }); + .then(() => cy.clearLocalStorageSnapshot("getting-started")) + .then(() => DataPipelinesBasePO.login()) + .then(() => cy.saveLocalStorage("getting-started")) + .then(() => cy.prepareLongLivedFailingTestJob()) + .then(() => cy.createExecutionsLongLivedFailingTestJob()) + .then(() => cy.fixture("e2e-cy-dp-failing.job.json")) + .then((failingTestJob) => { + testJob = applyGlobalEnvSettings(failingTestJob); + + return cy.wrap({ + context: "getting-started.spec::before()", + action: "continue", + }); + }); }); after(() => { @@ -34,109 +37,97 @@ describe('Getting Started Page', { tags: ['@dataPipelines'] }, () => { }); beforeEach(() => { - cy.restoreLocalStorage('getting-started'); + cy.restoreLocalStorage("getting-started"); DataPipelinesBasePO.initBackendRequestInterceptor(); }); - it('Main Title Component have text: Get Started with Data Pipelines', () => { - GettingStartedPage - .navigateTo() + it("Main Title Component have text: Get Started with Data Pipelines", () => { + GettingStartedPage.navigateTo() .getMainTitle() - .should('have.text', 'Get Started with Data Pipelines'); + .should("have.text", "Get Started with Data Pipelines"); }); - describe('Data Jobs Health Overview Panel', () => { - it('Verify Widgets rendered correct data and failing jobs navigates correctly', () => { - GettingStartedPage - .navigateTo(); + describe("Data Jobs Health Overview Panel", () => { + it("Verify Widgets rendered correct data and failing jobs navigates correctly", () => { + GettingStartedPage.navigateTo(); - let dataJobsHealthPanel = DataJobsHealthPanelComponentPO - .getComponent(); - dataJobsHealthPanel - .waitForViewToRender(); - dataJobsHealthPanel - .getDataJobsHealthPanel() - .scrollIntoView(); + let dataJobsHealthPanel = + DataJobsHealthPanelComponentPO.getComponent(); + dataJobsHealthPanel.waitForViewToRender(); + dataJobsHealthPanel.getDataJobsHealthPanel().scrollIntoView(); dataJobsHealthPanel .getExecutionsSuccessPercentage() - .should('be.gte', 0) - .should('be.lte', 100); + .should("be.gte", 0) + .should("be.lte", 100); dataJobsHealthPanel .getNumberOfFailedExecutions() - .should('be.gte', 2); - dataJobsHealthPanel - .getExecutionsTotal() - .should('be.gte', 2); + .should("be.gte", 2); + dataJobsHealthPanel.getExecutionsTotal().should("be.gte", 2); dataJobsHealthPanel .getAllFailingJobs() - .should('have.length.gte', 1); + .should("have.length.gte", 1); dataJobsHealthPanel .getAllMostRecentFailingJobsExecutions() - .should('have.length.gte', 1); + .should("have.length.gte", 1); // navigate to failing job details - dataJobsHealthPanel - .navigateToFailingJobDetails(testJob.job_name); + dataJobsHealthPanel.navigateToFailingJobDetails(testJob.job_name); - const dataJobManageDetailsPage = DataJobManageDetailsPage - .getPage(); + const dataJobManageDetailsPage = DataJobManageDetailsPage.getPage(); dataJobManageDetailsPage .getMainTitle() - .should('contain.text', testJob.job_name); + .should("contain.text", testJob.job_name); dataJobManageDetailsPage .getDetailsTab() - .should('be.visible') - .should('have.class', 'active'); + .should("be.visible") + .should("have.class", "active"); dataJobManageDetailsPage .getExecutionsTab() - .should('exist') - .should('not.have.class', 'active'); + .should("exist") + .should("not.have.class", "active"); dataJobManageDetailsPage .showMoreDescription() .getDescriptionFull() - .should('contain.text', testJob.description); + .should("contain.text", testJob.description); }); - it('Verify most recent failing executions Widget navigates correctly', () => { - GettingStartedPage - .navigateTo(); + it("Verify most recent failing executions Widget navigates correctly", () => { + GettingStartedPage.navigateTo(); - let dataJobsHealthPanel = DataJobsHealthPanelComponentPO - .getComponent(); - dataJobsHealthPanel - .waitForViewToRender(); - dataJobsHealthPanel - .getDataJobsHealthPanel() - .scrollIntoView(); + let dataJobsHealthPanel = + DataJobsHealthPanelComponentPO.getComponent(); + dataJobsHealthPanel.waitForViewToRender(); + dataJobsHealthPanel.getDataJobsHealthPanel().scrollIntoView(); dataJobsHealthPanel .getAllMostRecentFailingJobsExecutions() - .should('have.length.gte', 1); + .should("have.length.gte", 1); // navigate to most recent failing job executions - dataJobsHealthPanel - .navigateToMostRecentFailingJobExecutions(testJob.job_name); + dataJobsHealthPanel.navigateToMostRecentFailingJobExecutions( + testJob.job_name + ); - const dataJobManageExecutionsPage = DataJobManageExecutionsPage - .getPage(); + const dataJobManageExecutionsPage = + DataJobManageExecutionsPage.getPage(); dataJobManageExecutionsPage .getMainTitle() - .should('contain.text', testJob.job_name); + .should("contain.text", testJob.job_name); dataJobManageExecutionsPage .getDetailsTab() - .should('be.visible') - .should('not.have.class', 'active'); + .should("be.visible") + .should("not.have.class", "active"); dataJobManageExecutionsPage .getExecutionsTab() - .should('be.visible') - .should('have.class', 'active'); + .should("be.visible") + .should("have.class", "active"); dataJobManageExecutionsPage .getDataGridRows() - .should('have.length.gte', 1); + .should("have.length.gte", 1); }); }); }); diff --git a/projects/frontend/data-pipelines/gui/e2e/integration/lib/explore/data-job-details.spec.js b/projects/frontend/data-pipelines/gui/e2e/integration/lib/explore/data-job-details.spec.js index e876c43134..d801af54e1 100644 --- a/projects/frontend/data-pipelines/gui/e2e/integration/lib/explore/data-job-details.spec.js +++ b/projects/frontend/data-pipelines/gui/e2e/integration/lib/explore/data-job-details.spec.js @@ -4,153 +4,180 @@ */ /// -import { DataJobsExplorePage } from '../../../support/pages/app/lib/explore/data-jobs.po'; -import { DataJobExploreDetailsPage } from '../../../support/pages/app/lib/explore/data-job-details.po'; -import { applyGlobalEnvSettings } from '../../../support/helpers/commands.helpers'; - -describe('Data Job Explore Details Page', { tags: ['@dataPipelines', '@exploreDataJobDetails'] }, () => { - let dataJobExploreDetailsPage; - let testJobs; - - before(() => { - return DataJobExploreDetailsPage.recordHarIfSupported() - .then(() => cy.clearLocalStorageSnapshot('data-job-explore-details')) - .then(() => DataJobExploreDetailsPage.login()) - .then(() => cy.saveLocalStorage('data-job-explore-details')) - .then(() => cy.cleanTestJobs()) - .then(() => cy.prepareBaseTestJobs()) - .then(() => cy.fixture('lib/explore/test-jobs.json')) - .then((loadedTestJobs) => { - testJobs = applyGlobalEnvSettings(loadedTestJobs); - - return cy.wrap({ context: 'explore::data-job-details.spec::before()', action: 'continue' }); - }); - }); - - after(() => { - cy.cleanTestJobs(); - - DataJobExploreDetailsPage.saveHarIfSupported(); - }); - - beforeEach(() => { - cy.restoreLocalStorage('data-job-explore-details'); - - DataJobExploreDetailsPage.initBackendRequestInterceptor(); - }); - - it('Data Job Explore Details Page - should load and show job details', () => { - cy.log('Fixture for name: ' + testJobs[0].job_name); - - const dataJobsExplorePage = DataJobsExplorePage.navigateTo(); - - dataJobsExplorePage - .openJobDetails(testJobs[0].team, testJobs[0].job_name); - - dataJobExploreDetailsPage = DataJobExploreDetailsPage - .getPage(); - - dataJobExploreDetailsPage - .getDetailsTab() - .should('be.visible'); - - dataJobExploreDetailsPage - .getMainTitle() - .should('be.visible') - .should('contains.text', testJobs[0].job_name); - - dataJobExploreDetailsPage - .getStatusField() - .should('be.visible') - .should('have.text', 'Not Deployed'); - - dataJobExploreDetailsPage - .getDescriptionField() - .should('be.visible') - .should('contain.text', testJobs[0].description); - - dataJobExploreDetailsPage - .getTeamField() - .should('be.visible') - .should('have.text', testJobs[0].team); - - dataJobExploreDetailsPage - .getScheduleField() - .should('be.visible') - .should('contains.text', 'At 12:00 AM, on day 01 of the month, and on Friday'); - - // DISABLED Because there is no Source at the moment. - // dataJobExploreDetailsPage - // .getSourceField() - // .should('be.visible') - // .should('contains.text', 'http://host/data-jobs/' + testJobs[0].job_name) - // .should("have.attr", "href", 'http://host/data-jobs/' + testJobs[0].job_name); - - dataJobExploreDetailsPage - .getOnDeployedField() - .should('be.visible') - .should('contains.text', testJobs[0].config.contacts.notified_on_job_deploy); - - dataJobExploreDetailsPage - .getOnPlatformErrorField() - .should('be.visible') - .should('contains.text', testJobs[0].config.contacts.notified_on_job_failure_platform_error); - - dataJobExploreDetailsPage - .getOnUserErrorField() - .should('be.visible') - .should('contains.text', testJobs[0].config.contacts.notified_on_job_failure_user_error); - - dataJobExploreDetailsPage - .getOnSuccessField() - .should('be.visible') - .should('contains.text', testJobs[0].config.contacts.notified_on_job_success); - }); - - it('Data Job Explore Details Page - should verify Details tab is visible and active', () => { - cy.log('Fixture for name: ' + testJobs[0].job_name); - - const dataJobsExplorePage = DataJobsExplorePage.navigateTo(); - - dataJobsExplorePage - .openJobDetails(testJobs[0].team, testJobs[0].job_name); - - const dataJobExploreDetailsPage = DataJobExploreDetailsPage - .getPage(); - - dataJobExploreDetailsPage - .getMainTitle() - .should('be.visible') - .should('contains.text', testJobs[0].job_name); - - dataJobExploreDetailsPage - .getDetailsTab() - .should('be.visible') - .should('have.class', 'active'); - }); - - it('Data Job Explore Details Page - should verify Action buttons are not displayed', () => { - cy.log('Fixture for name: ' + testJobs[0].job_name); - - const dataJobsExplorePage = DataJobsExplorePage.navigateTo(); - - dataJobsExplorePage - .openJobDetails(testJobs[0].team, testJobs[0].job_name); - - const dataJobExploreDetailsPage = DataJobExploreDetailsPage - .getPage(); - - dataJobExploreDetailsPage - .getMainTitle() - .should('be.visible') - .should('contains.text', testJobs[0].job_name); - - dataJobExploreDetailsPage - .getExecuteNowButton() - .should('not.exist'); - - dataJobExploreDetailsPage - .getActionDropdownBtn() - .should('not.exist'); - }); -}); +import { DataJobsExplorePage } from "../../../support/pages/app/lib/explore/data-jobs.po"; +import { DataJobExploreDetailsPage } from "../../../support/pages/app/lib/explore/data-job-details.po"; +import { applyGlobalEnvSettings } from "../../../support/helpers/commands.helpers"; + +describe( + "Data Job Explore Details Page", + { tags: ["@dataPipelines", "@exploreDataJobDetails"] }, + () => { + let dataJobExploreDetailsPage; + let testJobs; + + before(() => { + return DataJobExploreDetailsPage.recordHarIfSupported() + .then(() => + cy.clearLocalStorageSnapshot("data-job-explore-details") + ) + .then(() => DataJobExploreDetailsPage.login()) + .then(() => cy.saveLocalStorage("data-job-explore-details")) + .then(() => cy.cleanTestJobs()) + .then(() => cy.prepareBaseTestJobs()) + .then(() => cy.fixture("lib/explore/test-jobs.json")) + .then((loadedTestJobs) => { + testJobs = applyGlobalEnvSettings(loadedTestJobs); + + return cy.wrap({ + context: "explore::data-job-details.spec::before()", + action: "continue", + }); + }); + }); + + after(() => { + cy.cleanTestJobs(); + + DataJobExploreDetailsPage.saveHarIfSupported(); + }); + + beforeEach(() => { + cy.restoreLocalStorage("data-job-explore-details"); + + DataJobExploreDetailsPage.initBackendRequestInterceptor(); + }); + + it("Data Job Explore Details Page - should load and show job details", () => { + cy.log("Fixture for name: " + testJobs[0].job_name); + + const dataJobsExplorePage = DataJobsExplorePage.navigateTo(); + + dataJobsExplorePage.openJobDetails( + testJobs[0].team, + testJobs[0].job_name + ); + + dataJobExploreDetailsPage = DataJobExploreDetailsPage.getPage(); + + dataJobExploreDetailsPage.getDetailsTab().should("be.visible"); + + dataJobExploreDetailsPage + .getMainTitle() + .should("be.visible") + .should("contains.text", testJobs[0].job_name); + + dataJobExploreDetailsPage + .getStatusField() + .should("be.visible") + .should("have.text", "Not Deployed"); + + dataJobExploreDetailsPage + .getDescriptionField() + .should("be.visible") + .should("contain.text", testJobs[0].description); + + dataJobExploreDetailsPage + .getTeamField() + .should("be.visible") + .should("have.text", testJobs[0].team); + + dataJobExploreDetailsPage + .getScheduleField() + .should("be.visible") + .should( + "contains.text", + "At 12:00 AM, on day 01 of the month, and on Friday" + ); + + // DISABLED Because there is no Source at the moment. + // dataJobExploreDetailsPage + // .getSourceField() + // .should('be.visible') + // .should('contains.text', 'http://host/data-jobs/' + testJobs[0].job_name) + // .should("have.attr", "href", 'http://host/data-jobs/' + testJobs[0].job_name); + + dataJobExploreDetailsPage + .getOnDeployedField() + .should("be.visible") + .should( + "contains.text", + testJobs[0].config.contacts.notified_on_job_deploy + ); + + dataJobExploreDetailsPage + .getOnPlatformErrorField() + .should("be.visible") + .should( + "contains.text", + testJobs[0].config.contacts + .notified_on_job_failure_platform_error + ); + + dataJobExploreDetailsPage + .getOnUserErrorField() + .should("be.visible") + .should( + "contains.text", + testJobs[0].config.contacts + .notified_on_job_failure_user_error + ); + + dataJobExploreDetailsPage + .getOnSuccessField() + .should("be.visible") + .should( + "contains.text", + testJobs[0].config.contacts.notified_on_job_success + ); + }); + + it("Data Job Explore Details Page - should verify Details tab is visible and active", () => { + cy.log("Fixture for name: " + testJobs[0].job_name); + + const dataJobsExplorePage = DataJobsExplorePage.navigateTo(); + + dataJobsExplorePage.openJobDetails( + testJobs[0].team, + testJobs[0].job_name + ); + + const dataJobExploreDetailsPage = + DataJobExploreDetailsPage.getPage(); + + dataJobExploreDetailsPage + .getMainTitle() + .should("be.visible") + .should("contains.text", testJobs[0].job_name); + + dataJobExploreDetailsPage + .getDetailsTab() + .should("be.visible") + .should("have.class", "active"); + }); + + it("Data Job Explore Details Page - should verify Action buttons are not displayed", () => { + cy.log("Fixture for name: " + testJobs[0].job_name); + + const dataJobsExplorePage = DataJobsExplorePage.navigateTo(); + + dataJobsExplorePage.openJobDetails( + testJobs[0].team, + testJobs[0].job_name + ); + + const dataJobExploreDetailsPage = + DataJobExploreDetailsPage.getPage(); + + dataJobExploreDetailsPage + .getMainTitle() + .should("be.visible") + .should("contains.text", testJobs[0].job_name); + + dataJobExploreDetailsPage.getExecuteNowButton().should("not.exist"); + + dataJobExploreDetailsPage + .getActionDropdownBtn() + .should("not.exist"); + }); + } +); diff --git a/projects/frontend/data-pipelines/gui/e2e/integration/lib/explore/data-job-executions.spec.js b/projects/frontend/data-pipelines/gui/e2e/integration/lib/explore/data-job-executions.spec.js index b346dfb456..1d5077d5b5 100644 --- a/projects/frontend/data-pipelines/gui/e2e/integration/lib/explore/data-job-executions.spec.js +++ b/projects/frontend/data-pipelines/gui/e2e/integration/lib/explore/data-job-executions.spec.js @@ -5,80 +5,90 @@ /// -import { DataJobsExplorePage } from '../../../support/pages/app/lib/explore/data-jobs.po'; -import { DataJobBasePO } from '../../../support/application/data-job-base.po'; -import { applyGlobalEnvSettings } from '../../../support/helpers/commands.helpers'; - -describe('Data Job Explore Executions Page', { tags: ['@dataPipelines', '@exploreDataJobExecutions'] }, () => { - let testJobs; - - before(() => { - return DataJobBasePO.recordHarIfSupported() - .then(() => cy.clearLocalStorageSnapshot('data-job-explore-executions')) - .then(() => DataJobBasePO.login()) - .then(() => cy.saveLocalStorage('data-job-explore-executions')) - .then(() => cy.cleanTestJobs()) - .then(() => cy.prepareBaseTestJobs()) - .then(() => cy.fixture('lib/explore/test-jobs.json')) - .then((loadedTestJobs) => { - testJobs = applyGlobalEnvSettings(loadedTestJobs); - - return cy.wrap({ context: 'explore::data-job-executions.spec::before()', action: 'continue' }); - }); - }); - - after(() => { - cy.cleanTestJobs(); - - DataJobBasePO.saveHarIfSupported(); - }); - - beforeEach(() => { - cy.restoreLocalStorage('data-job-explore-executions'); - - DataJobBasePO.initBackendRequestInterceptor(); - }); - - it(`Data Job Explore Executions Page - should open Details and verify Executions tab is not displayed`, () => { - cy.log('Fixture for name: ' + testJobs[0].job_name); - - const dataJobsExplorePage = DataJobsExplorePage.navigateTo(); - - dataJobsExplorePage - .openJobDetails(testJobs[0].team, testJobs[0].job_name); - - const dataJobBasePage = DataJobBasePO - .getPage(); - - dataJobBasePage - .getMainTitle() - .should('be.visible') - .should('contains.text', testJobs[0].job_name); - - dataJobBasePage - .getDetailsTab() - .should('have.class', 'active'); - - dataJobBasePage - .getExecutionsTab() - .should('not.exist'); - }); - - it('Data Job Explore Executions Page - should verify on URL navigate to Executions will redirect to Details', () => { - const dataJobBasePage = DataJobBasePO - .navigateToUrl(`/explore/data-jobs/${ testJobs[0].team }/${ testJobs[0].job_name }/executions`); - - dataJobBasePage - .getMainTitle() - .should('be.visible') - .should('contains.text', testJobs[0].job_name); - - dataJobBasePage - .getCurrentUrl() - .should('match', new RegExp(`\\/explore\\/data-jobs\\/${testJobs[0].team}\\/${testJobs[0].job_name}\\/details$`)); - - dataJobBasePage - .getDetailsTab() - .should('have.class', 'active'); - }); -}); +import { DataJobsExplorePage } from "../../../support/pages/app/lib/explore/data-jobs.po"; +import { DataJobBasePO } from "../../../support/application/data-job-base.po"; +import { applyGlobalEnvSettings } from "../../../support/helpers/commands.helpers"; + +describe( + "Data Job Explore Executions Page", + { tags: ["@dataPipelines", "@exploreDataJobExecutions"] }, + () => { + let testJobs; + + before(() => { + return DataJobBasePO.recordHarIfSupported() + .then(() => + cy.clearLocalStorageSnapshot("data-job-explore-executions") + ) + .then(() => DataJobBasePO.login()) + .then(() => cy.saveLocalStorage("data-job-explore-executions")) + .then(() => cy.cleanTestJobs()) + .then(() => cy.prepareBaseTestJobs()) + .then(() => cy.fixture("lib/explore/test-jobs.json")) + .then((loadedTestJobs) => { + testJobs = applyGlobalEnvSettings(loadedTestJobs); + + return cy.wrap({ + context: "explore::data-job-executions.spec::before()", + action: "continue", + }); + }); + }); + + after(() => { + cy.cleanTestJobs(); + + DataJobBasePO.saveHarIfSupported(); + }); + + beforeEach(() => { + cy.restoreLocalStorage("data-job-explore-executions"); + + DataJobBasePO.initBackendRequestInterceptor(); + }); + + it(`Data Job Explore Executions Page - should open Details and verify Executions tab is not displayed`, () => { + cy.log("Fixture for name: " + testJobs[0].job_name); + + const dataJobsExplorePage = DataJobsExplorePage.navigateTo(); + + dataJobsExplorePage.openJobDetails( + testJobs[0].team, + testJobs[0].job_name + ); + + const dataJobBasePage = DataJobBasePO.getPage(); + + dataJobBasePage + .getMainTitle() + .should("be.visible") + .should("contains.text", testJobs[0].job_name); + + dataJobBasePage.getDetailsTab().should("have.class", "active"); + + dataJobBasePage.getExecutionsTab().should("not.exist"); + }); + + it("Data Job Explore Executions Page - should verify on URL navigate to Executions will redirect to Details", () => { + const dataJobBasePage = DataJobBasePO.navigateToUrl( + `/explore/data-jobs/${testJobs[0].team}/${testJobs[0].job_name}/executions` + ); + + dataJobBasePage + .getMainTitle() + .should("be.visible") + .should("contains.text", testJobs[0].job_name); + + dataJobBasePage + .getCurrentUrl() + .should( + "match", + new RegExp( + `\\/explore\\/data-jobs\\/${testJobs[0].team}\\/${testJobs[0].job_name}\\/details$` + ) + ); + + dataJobBasePage.getDetailsTab().should("have.class", "active"); + }); + } +); diff --git a/projects/frontend/data-pipelines/gui/e2e/integration/lib/explore/data-jobs.spec.js b/projects/frontend/data-pipelines/gui/e2e/integration/lib/explore/data-jobs.spec.js index 9877cef132..715cfe826b 100644 --- a/projects/frontend/data-pipelines/gui/e2e/integration/lib/explore/data-jobs.spec.js +++ b/projects/frontend/data-pipelines/gui/e2e/integration/lib/explore/data-jobs.spec.js @@ -4,303 +4,323 @@ */ /// -import { DataJobsExplorePage } from '../../../support/pages/app/lib/explore/data-jobs.po'; -import { DataJobExploreDetailsPage } from '../../../support/pages/app/lib/explore/data-job-details.po'; -import { applyGlobalEnvSettings } from '../../../support/helpers/commands.helpers'; +import { DataJobsExplorePage } from "../../../support/pages/app/lib/explore/data-jobs.po"; +import { DataJobExploreDetailsPage } from "../../../support/pages/app/lib/explore/data-job-details.po"; +import { applyGlobalEnvSettings } from "../../../support/helpers/commands.helpers"; + +describe( + "Data Jobs Explore Page", + { tags: ["@dataPipelines", "@exploreDataJobs"] }, + () => { + let dataJobsExplorePage; + let testJobs; + + before(() => { + return DataJobsExplorePage.recordHarIfSupported() + .then(() => cy.clearLocalStorageSnapshot("data-jobs-explore")) + .then(() => DataJobsExplorePage.login()) + .then(() => cy.saveLocalStorage("data-jobs-explore")) + .then(() => cy.cleanTestJobs()) + .then(() => cy.prepareBaseTestJobs()) + .then(() => cy.fixture("lib/explore/test-jobs.json")) + .then((loadedTestJobs) => { + testJobs = applyGlobalEnvSettings(loadedTestJobs); + + return cy.wrap({ + context: "explore::data-jobs.spec::before()", + action: "continue", + }); + }); + }); -describe('Data Jobs Explore Page', { tags: ['@dataPipelines', '@exploreDataJobs'] }, () => { - let dataJobsExplorePage; - let testJobs; + after(() => { + cy.cleanTestJobs(); - before(() => { - return DataJobsExplorePage.recordHarIfSupported() - .then(() => cy.clearLocalStorageSnapshot('data-jobs-explore')) - .then(() => DataJobsExplorePage.login()) - .then(() => cy.saveLocalStorage('data-jobs-explore')) - .then(() => cy.cleanTestJobs()) - .then(() => cy.prepareBaseTestJobs()) - .then(() => cy.fixture('lib/explore/test-jobs.json')) - .then((loadedTestJobs) => { - testJobs = applyGlobalEnvSettings(loadedTestJobs); + DataJobsExplorePage.saveHarIfSupported(); + }); - return cy.wrap({ context: 'explore::data-jobs.spec::before()', action: 'continue' }); - }); - }); + beforeEach(() => { + cy.restoreLocalStorage("data-jobs-explore"); - after(() => { - cy.cleanTestJobs(); + DataJobsExplorePage.initBackendRequestInterceptor(); + }); - DataJobsExplorePage.saveHarIfSupported(); - }); + it("Main Title Component have text: Explore Data Jobs", () => { + dataJobsExplorePage = DataJobsExplorePage.navigateTo(); - beforeEach(() => { - cy.restoreLocalStorage('data-jobs-explore'); + dataJobsExplorePage + .getMainTitle() + .should("be.visible") + .should("have.text", "Explore Data Jobs"); + }); - DataJobsExplorePage.initBackendRequestInterceptor(); - }); + it("Data Jobs Explore Page - loaded and shows data jobs", () => { + dataJobsExplorePage = DataJobsExplorePage.navigateTo(); - it('Main Title Component have text: Explore Data Jobs', () => { - dataJobsExplorePage = DataJobsExplorePage.navigateTo(); + dataJobsExplorePage.getDataGrid().should("be.visible"); + + testJobs.forEach((testJob) => { + cy.log("Fixture for name: " + testJob.job_name); + + dataJobsExplorePage + .getDataGridCell(testJob.job_name) + .scrollIntoView() + .should("be.visible"); + + dataJobsExplorePage + .getDataGridCell(testJob.team) + .should("be.visible"); + }); + }); - dataJobsExplorePage - .getMainTitle() - .should('be.visible') - .should('have.text', 'Explore Data Jobs'); - }); + it("Data Jobs Explore Page - filters data jobs", () => { + cy.log("Fixture for name: " + testJobs[0].job_name); - it('Data Jobs Explore Page - loaded and shows data jobs', () => { - dataJobsExplorePage = DataJobsExplorePage.navigateTo(); + dataJobsExplorePage = DataJobsExplorePage.navigateTo(); - dataJobsExplorePage - .getDataGrid() - .should('be.visible'); + dataJobsExplorePage.filterByJobName(testJobs[0].job_name); - testJobs.forEach((testJob) => { - cy.log('Fixture for name: ' + testJob.job_name); + dataJobsExplorePage + .getDataGridCell(testJobs[0].job_name) + .should("be.visible"); dataJobsExplorePage - .getDataGridCell(testJob.job_name) - .scrollIntoView() - .should('be.visible'); + .getDataGridCell(testJobs[1].job_name) + .should("not.exist"); + }); + + it("Data Jobs Explore Page - refreshes data jobs", () => { + dataJobsExplorePage = DataJobsExplorePage.navigateTo(); + + cy.fixture("lib/explore/additional-test-job.json").then( + (additionalTestJob) => { + const normalizedTestJob = + applyGlobalEnvSettings(additionalTestJob); + + cy.log("Fixture for name: " + normalizedTestJob.job_name); + + dataJobsExplorePage + .getDataGridCell(testJobs[0].job_name) + .should("have.text", testJobs[0].job_name); + + dataJobsExplorePage + .getDataGridCell(normalizedTestJob.job_name) + .should("not.exist"); + + cy.prepareAdditionalTestJobs(); + + dataJobsExplorePage.refreshDataGrid(); + + dataJobsExplorePage.filterByJobName( + normalizedTestJob.job_name + ); + + dataJobsExplorePage + .getDataGridCell(normalizedTestJob.job_name) + .should("have.text", normalizedTestJob.job_name); + } + ); + }); + + it("Data Jobs Explore Page - searches data jobs", () => { + cy.log("Fixture for name: " + testJobs[0].job_name); + + dataJobsExplorePage = DataJobsExplorePage.navigateTo(); + + dataJobsExplorePage + .getDataGridCell(testJobs[1].job_name) + .should("be.visible"); + + dataJobsExplorePage.searchByJobName(testJobs[0].job_name); + + dataJobsExplorePage + .getDataGridCell(testJobs[0].job_name) + .should("be.visible"); + + dataJobsExplorePage + .getDataGridCell(testJobs[1].job_name) + .should("not.exist"); + }); + + it("Data Jobs Explore Page - searches data jobs, search parameter goes into URL", () => { + cy.log("Fixture for name: " + testJobs[0].job_name); + + dataJobsExplorePage = DataJobsExplorePage.navigateTo(); + // verify 2 test rows visible dataJobsExplorePage - .getDataGridCell(testJob.team) - .should('be.visible'); - }) - }); + .getDataGridCell(testJobs[0].job_name) + .should("be.visible"); + dataJobsExplorePage + .getDataGridCell(testJobs[1].job_name) + .should("be.visible"); - it('Data Jobs Explore Page - filters data jobs', () => { - cy.log('Fixture for name: ' + testJobs[0].job_name); + // do search + dataJobsExplorePage.searchByJobName(testJobs[0].job_name); - dataJobsExplorePage = DataJobsExplorePage.navigateTo(); + // verify 1 test row visible + dataJobsExplorePage + .getDataGridCell(testJobs[0].job_name) + .should("be.visible"); + dataJobsExplorePage + .getDataGridCell(testJobs[1].job_name) + .should("not.exist"); - dataJobsExplorePage - .filterByJobName(testJobs[0].job_name); + // verify url contains search value + dataJobsExplorePage + .getCurrentUrl() + .should( + "match", + new RegExp( + `\\/explore\\/data-jobs\\?search=${testJobs[0].job_name}$` + ) + ); + + // clear search with clear() method + dataJobsExplorePage.clearSearchField(); + + // verify 2 test rows visible + dataJobsExplorePage + .getDataGridCell(testJobs[0].job_name) + .should("be.visible"); + dataJobsExplorePage + .getDataGridCell(testJobs[1].job_name) + .should("be.visible"); - dataJobsExplorePage - .getDataGridCell(testJobs[0].job_name) - .should('be.visible'); + // verify url does not contain search value + dataJobsExplorePage + .getCurrentUrl() + .should("match", new RegExp(`\\/explore\\/data-jobs$`)); + }); - dataJobsExplorePage - .getDataGridCell(testJobs[1].job_name) - .should('not.exist'); - }); + it("Data Jobs Explore Page - searches data jobs, perform search when URL contains search parameter", () => { + cy.log("Fixture for name: " + testJobs[1].job_name); - it('Data Jobs Explore Page - refreshes data jobs', () => { - dataJobsExplorePage = DataJobsExplorePage.navigateTo(); + // navigate with search value in URL + dataJobsExplorePage = DataJobsExplorePage.navigateToUrl( + `/explore/data-jobs?search=${testJobs[1].job_name}` + ); - cy.fixture('lib/explore/additional-test-job.json').then((additionalTestJob) => { - const normalizedTestJob = applyGlobalEnvSettings(additionalTestJob); + // verify url contains search value + dataJobsExplorePage + .getCurrentUrl() + .should( + "match", + new RegExp( + `\\/explore\\/data-jobs\\?search=${testJobs[1].job_name}$` + ) + ); + + // verify 1 test row visible + dataJobsExplorePage + .getDataGridCell(testJobs[0].job_name) + .should("not.exist"); + dataJobsExplorePage + .getDataGridCell(testJobs[1].job_name) + .should("be.visible"); - cy.log('Fixture for name: ' + normalizedTestJob.job_name); + // clear search with button + dataJobsExplorePage.clearSearchFieldWithButton(); + // verify 2 test rows visible dataJobsExplorePage .getDataGridCell(testJobs[0].job_name) - .should('have.text', testJobs[0].job_name); + .should("be.visible"); + dataJobsExplorePage + .getDataGridCell(testJobs[1].job_name) + .should("be.visible"); + // verify url does not contain search value dataJobsExplorePage - .getDataGridCell(normalizedTestJob.job_name) - .should('not.exist'); + .getCurrentUrl() + .should("match", new RegExp(`\\/explore\\/data-jobs$`)); + }); + + it("Data Jobs Explore Page - show/hide column when toggling from menu", () => { + dataJobsExplorePage = DataJobsExplorePage.navigateTo(); - cy.prepareAdditionalTestJobs(); + // show panel for show/hide columns + dataJobsExplorePage.toggleColumnShowHidePanel(); + // verify correct options are rendered dataJobsExplorePage - .refreshDataGrid(); + .getDataGridColumnShowHideOptionsValues() + .should("have.length", 9) + .invoke("join", ",") + .should( + "eq", + "Description,Deployment Status,Last Execution Duration,Success rate,Next run (UTC),Last Deployed (UTC),Last Deployed By,Source,Logs" + ); + + // verify column is not checked in toggling menu + dataJobsExplorePage + .getDataGridColumnShowHideOption("Last Execution Duration") + .should("exist") + .should("not.be.checked"); + + // verify header cell for column is not rendered + dataJobsExplorePage + .getDataGridHeaderCell("Last Execution Duration") + .should("have.length", 0); + + // toggle column to render + dataJobsExplorePage.checkColumnShowHideOption( + "Last Execution Duration" + ); + + // verify column is checked in toggling menu + dataJobsExplorePage + .getDataGridColumnShowHideOption("Last Execution Duration") + .should("exist") + .should("be.checked"); + + // verify header cell for column is rendered + dataJobsExplorePage + .getDataGridHeaderCell("Last Execution Duration") + .should("have.length", 1); + + // toggle column to hide + dataJobsExplorePage.uncheckColumnShowHideOption( + "Last Execution Duration" + ); + // verify column is not checked in toggling menu dataJobsExplorePage - .filterByJobName(normalizedTestJob.job_name); + .getDataGridColumnShowHideOption("Last Execution Duration") + .should("exist") + .should("not.be.checked"); + // verify header cell for column is not rendered dataJobsExplorePage - .getDataGridCell(normalizedTestJob.job_name) - .should('have.text', normalizedTestJob.job_name); + .getDataGridHeaderCell("Last Execution Duration") + .should("have.length", 0); + + // hide panel for show/hide columns + dataJobsExplorePage.toggleColumnShowHidePanel(); + }); + + it("Data Jobs Explore Page - navigates to data job", () => { + cy.log("Fixture for name: " + testJobs[0].job_name); + + dataJobsExplorePage = DataJobsExplorePage.navigateTo(); + + dataJobsExplorePage.openJobDetails( + testJobs[0].team, + testJobs[0].job_name + ); + + const dataJobExploreDetailsPage = + DataJobExploreDetailsPage.getPage(); + + dataJobExploreDetailsPage + .getMainTitle() + .should("be.visible") + .should("contains.text", testJobs[0].job_name); + + dataJobExploreDetailsPage + .getDescriptionField() + .should("be.visible") + .should("contain.text", testJobs[0].description); }); - }); - - it('Data Jobs Explore Page - searches data jobs', () => { - cy.log('Fixture for name: ' + testJobs[0].job_name); - - dataJobsExplorePage = DataJobsExplorePage.navigateTo(); - - dataJobsExplorePage - .getDataGridCell(testJobs[1].job_name) - .should('be.visible'); - - dataJobsExplorePage - .searchByJobName(testJobs[0].job_name); - - dataJobsExplorePage - .getDataGridCell(testJobs[0].job_name) - .should('be.visible'); - - dataJobsExplorePage - .getDataGridCell(testJobs[1].job_name) - .should('not.exist'); - }); - - it('Data Jobs Explore Page - searches data jobs, search parameter goes into URL', () => { - cy.log('Fixture for name: ' + testJobs[0].job_name); - - dataJobsExplorePage = DataJobsExplorePage.navigateTo(); - - // verify 2 test rows visible - dataJobsExplorePage - .getDataGridCell(testJobs[0].job_name) - .should('be.visible'); - dataJobsExplorePage - .getDataGridCell(testJobs[1].job_name) - .should('be.visible'); - - // do search - dataJobsExplorePage - .searchByJobName(testJobs[0].job_name); - - // verify 1 test row visible - dataJobsExplorePage - .getDataGridCell(testJobs[0].job_name) - .should('be.visible'); - dataJobsExplorePage - .getDataGridCell(testJobs[1].job_name) - .should('not.exist'); - - // verify url contains search value - dataJobsExplorePage - .getCurrentUrl() - .should('match', new RegExp(`\\/explore\\/data-jobs\\?search=${ testJobs[0].job_name }$`)); - - // clear search with clear() method - dataJobsExplorePage - .clearSearchField(); - - // verify 2 test rows visible - dataJobsExplorePage - .getDataGridCell(testJobs[0].job_name) - .should('be.visible'); - dataJobsExplorePage - .getDataGridCell(testJobs[1].job_name) - .should('be.visible'); - - // verify url does not contain search value - dataJobsExplorePage - .getCurrentUrl() - .should('match', new RegExp(`\\/explore\\/data-jobs$`)); - }); - - it('Data Jobs Explore Page - searches data jobs, perform search when URL contains search parameter', () => { - cy.log('Fixture for name: ' + testJobs[1].job_name); - - // navigate with search value in URL - dataJobsExplorePage = DataJobsExplorePage.navigateToUrl(`/explore/data-jobs?search=${ testJobs[1].job_name }`); - - // verify url contains search value - dataJobsExplorePage - .getCurrentUrl() - .should('match', new RegExp(`\\/explore\\/data-jobs\\?search=${ testJobs[1].job_name }$`)); - - // verify 1 test row visible - dataJobsExplorePage - .getDataGridCell(testJobs[0].job_name) - .should('not.exist'); - dataJobsExplorePage - .getDataGridCell(testJobs[1].job_name) - .should('be.visible'); - - // clear search with button - dataJobsExplorePage - .clearSearchFieldWithButton(); - - // verify 2 test rows visible - dataJobsExplorePage - .getDataGridCell(testJobs[0].job_name) - .should('be.visible'); - dataJobsExplorePage - .getDataGridCell(testJobs[1].job_name) - .should('be.visible'); - - // verify url does not contain search value - dataJobsExplorePage - .getCurrentUrl() - .should('match', new RegExp(`\\/explore\\/data-jobs$`)); - }); - - it('Data Jobs Explore Page - show/hide column when toggling from menu', () => { - dataJobsExplorePage = DataJobsExplorePage.navigateTo(); - - // show panel for show/hide columns - dataJobsExplorePage - .toggleColumnShowHidePanel(); - - // verify correct options are rendered - dataJobsExplorePage - .getDataGridColumnShowHideOptionsValues() - .should('have.length', 9) - .invoke('join', ',') - .should('eq', 'Description,Deployment Status,Last Execution Duration,Success rate,Next run (UTC),Last Deployed (UTC),Last Deployed By,Source,Logs'); - - // verify column is not checked in toggling menu - dataJobsExplorePage - .getDataGridColumnShowHideOption('Last Execution Duration') - .should('exist') - .should('not.be.checked'); - - // verify header cell for column is not rendered - dataJobsExplorePage - .getDataGridHeaderCell('Last Execution Duration') - .should('have.length', 0); - - // toggle column to render - dataJobsExplorePage - .checkColumnShowHideOption('Last Execution Duration'); - - // verify column is checked in toggling menu - dataJobsExplorePage - .getDataGridColumnShowHideOption('Last Execution Duration') - .should('exist') - .should('be.checked'); - - // verify header cell for column is rendered - dataJobsExplorePage - .getDataGridHeaderCell('Last Execution Duration') - .should('have.length', 1); - - // toggle column to hide - dataJobsExplorePage - .uncheckColumnShowHideOption('Last Execution Duration'); - - // verify column is not checked in toggling menu - dataJobsExplorePage - .getDataGridColumnShowHideOption('Last Execution Duration') - .should('exist') - .should('not.be.checked'); - - // verify header cell for column is not rendered - dataJobsExplorePage - .getDataGridHeaderCell('Last Execution Duration') - .should('have.length', 0); - - // hide panel for show/hide columns - dataJobsExplorePage - .toggleColumnShowHidePanel(); - }); - - it('Data Jobs Explore Page - navigates to data job', () => { - cy.log('Fixture for name: ' + testJobs[0].job_name); - - dataJobsExplorePage = DataJobsExplorePage.navigateTo(); - - dataJobsExplorePage - .openJobDetails(testJobs[0].team, testJobs[0].job_name); - - const dataJobExploreDetailsPage = DataJobExploreDetailsPage - .getPage(); - - dataJobExploreDetailsPage - .getMainTitle() - .should('be.visible') - .should('contains.text', testJobs[0].job_name); - - dataJobExploreDetailsPage - .getDescriptionField() - .should('be.visible') - .should('contain.text', testJobs[0].description); - }); -}); + } +); diff --git a/projects/frontend/data-pipelines/gui/e2e/integration/lib/manage/data-job-details.int.spec.js b/projects/frontend/data-pipelines/gui/e2e/integration/lib/manage/data-job-details.int.spec.js index 8af498d8b1..f25c81ac09 100644 --- a/projects/frontend/data-pipelines/gui/e2e/integration/lib/manage/data-job-details.int.spec.js +++ b/projects/frontend/data-pipelines/gui/e2e/integration/lib/manage/data-job-details.int.spec.js @@ -5,216 +5,265 @@ /// -import { DataJobManageDetailsPage } from '../../../support/pages/app/lib/manage/data-job-details.po'; -import { DataJobsManagePage } from '../../../support/pages/app/lib/manage/data-jobs.po'; -import { applyGlobalEnvSettings } from '../../../support/helpers/commands.helpers'; - -describe('Data Job Manage Details Page', { tags: ['@dataPipelines', '@manageDataJobDetails'] }, () => { - const descriptionWordsBeforeTruncate = 12; - - let dataJobManageDetailsPage; - let testJobs; - let longLivedTestJob; - - before(() => { - return DataJobManageDetailsPage.recordHarIfSupported() - .then(() => cy.clearLocalStorageSnapshot('data-job-manage-details')) - .then(() => DataJobManageDetailsPage.login()) - .then(() => cy.saveLocalStorage('data-job-manage-details')) - .then(() => cy.cleanTestJobs()) - .then(() => cy.prepareLongLivedTestJob()) - .then(() => cy.createTwoExecutionsLongLivedTestJob()) - .then(() => cy.prepareBaseTestJobs()) - .then(() => cy.fixture('lib/explore/test-jobs.json')) - .then((loadedTestJobs) => { - testJobs = applyGlobalEnvSettings(loadedTestJobs); - - return cy.wrap({ context: 'manage::data-job-details.spec::1::before()', action: 'continue' }); - }) - .then(() => cy.fixture('lib/manage/e2e-cypress-dp-test.json')) - .then((loadedTestJob) => { - longLivedTestJob = applyGlobalEnvSettings(loadedTestJob); - - return cy.wrap({ context: 'manage::data-job-details.spec::2::before()', action: 'continue' }); - }); - }); - - after(() => { - cy.cleanTestJobs(); - - DataJobManageDetailsPage.saveHarIfSupported(); - }); - - beforeEach(() => { - cy.restoreLocalStorage('data-job-manage-details'); - - DataJobManageDetailsPage.initBackendRequestInterceptor(); - }); - - it('Data Job Manage Details Page - disable/enable job', { tags: '@integration' }, () => { - dataJobManageDetailsPage = DataJobManageDetailsPage - .navigateTo(longLivedTestJob.team, longLivedTestJob.job_name); - - dataJobManageDetailsPage.clickOnContentContainer(); - - //Toggle job status twice, enable to disable and vice versa. - dataJobManageDetailsPage.toggleJobStatus(longLivedTestJob.job_name); - dataJobManageDetailsPage.toggleJobStatus(longLivedTestJob.job_name); - }); - - it('Data Job Manage Details Page - edit job description', { tags: '@integration' }, () => { - let newDescription = 'Test if changing the description is working'; - - dataJobManageDetailsPage = DataJobManageDetailsPage - .navigateTo(testJobs[0].team, testJobs[0].job_name); - - dataJobManageDetailsPage.clickOnContentContainer(); - - dataJobManageDetailsPage - .openDescription(); +import { DataJobManageDetailsPage } from "../../../support/pages/app/lib/manage/data-job-details.po"; +import { DataJobsManagePage } from "../../../support/pages/app/lib/manage/data-jobs.po"; +import { applyGlobalEnvSettings } from "../../../support/helpers/commands.helpers"; + +describe( + "Data Job Manage Details Page", + { tags: ["@dataPipelines", "@manageDataJobDetails"] }, + () => { + const descriptionWordsBeforeTruncate = 12; + + let dataJobManageDetailsPage; + let testJobs; + let longLivedTestJob; + + before(() => { + return DataJobManageDetailsPage.recordHarIfSupported() + .then(() => + cy.clearLocalStorageSnapshot("data-job-manage-details") + ) + .then(() => DataJobManageDetailsPage.login()) + .then(() => cy.saveLocalStorage("data-job-manage-details")) + .then(() => cy.cleanTestJobs()) + .then(() => cy.prepareLongLivedTestJob()) + .then(() => cy.createTwoExecutionsLongLivedTestJob()) + .then(() => cy.prepareBaseTestJobs()) + .then(() => cy.fixture("lib/explore/test-jobs.json")) + .then((loadedTestJobs) => { + testJobs = applyGlobalEnvSettings(loadedTestJobs); + + return cy.wrap({ + context: "manage::data-job-details.spec::1::before()", + action: "continue", + }); + }) + .then(() => cy.fixture("lib/manage/e2e-cypress-dp-test.json")) + .then((loadedTestJob) => { + longLivedTestJob = applyGlobalEnvSettings(loadedTestJob); + + return cy.wrap({ + context: "manage::data-job-details.spec::2::before()", + action: "continue", + }); + }); + }); - dataJobManageDetailsPage - .enterDescriptionDetails(newDescription); + after(() => { + cy.cleanTestJobs(); - dataJobManageDetailsPage - .saveDescription(); + DataJobManageDetailsPage.saveHarIfSupported(); + }); - dataJobManageDetailsPage - .getDescription() - .should('be.visible') - .should('contain.text', newDescription.split(' ').slice(0, descriptionWordsBeforeTruncate).join(' ')); - }); + beforeEach(() => { + cy.restoreLocalStorage("data-job-manage-details"); - it('Data Job Manage Details Page - execute now', () => { - dataJobManageDetailsPage = DataJobManageDetailsPage - .navigateTo(longLivedTestJob.team, longLivedTestJob.job_name); + DataJobManageDetailsPage.initBackendRequestInterceptor(); + }); - dataJobManageDetailsPage - .waitForTestJobExecutionCompletion(); + it( + "Data Job Manage Details Page - disable/enable job", + { tags: "@integration" }, + () => { + dataJobManageDetailsPage = DataJobManageDetailsPage.navigateTo( + longLivedTestJob.team, + longLivedTestJob.job_name + ); + + dataJobManageDetailsPage.clickOnContentContainer(); + + //Toggle job status twice, enable to disable and vice versa. + dataJobManageDetailsPage.toggleJobStatus( + longLivedTestJob.job_name + ); + dataJobManageDetailsPage.toggleJobStatus( + longLivedTestJob.job_name + ); + } + ); + + it( + "Data Job Manage Details Page - edit job description", + { tags: "@integration" }, + () => { + let newDescription = + "Test if changing the description is working"; + + dataJobManageDetailsPage = DataJobManageDetailsPage.navigateTo( + testJobs[0].team, + testJobs[0].job_name + ); + + dataJobManageDetailsPage.clickOnContentContainer(); + + dataJobManageDetailsPage.openDescription(); + + dataJobManageDetailsPage.enterDescriptionDetails( + newDescription + ); + + dataJobManageDetailsPage.saveDescription(); + + dataJobManageDetailsPage + .getDescription() + .should("be.visible") + .should( + "contain.text", + newDescription + .split(" ") + .slice(0, descriptionWordsBeforeTruncate) + .join(" ") + ); + } + ); - dataJobManageDetailsPage - .executeNow(); + it("Data Job Manage Details Page - execute now", () => { + dataJobManageDetailsPage = DataJobManageDetailsPage.navigateTo( + longLivedTestJob.team, + longLivedTestJob.job_name + ); - dataJobManageDetailsPage - .confirmInConfirmDialog(); + dataJobManageDetailsPage.waitForTestJobExecutionCompletion(); - dataJobManageDetailsPage - .getToastTitle(10000) - .should('exist') - .contains(/Data job Queued for execution|Failed, Data job is already executing/); - }); + dataJobManageDetailsPage.executeNow(); - it('Data Job Manage Details Page - download job key', () => { - dataJobManageDetailsPage = DataJobManageDetailsPage - .navigateTo(longLivedTestJob.team, longLivedTestJob.job_name); + dataJobManageDetailsPage.confirmInConfirmDialog(); - dataJobManageDetailsPage - .openActionDropdown(); + dataJobManageDetailsPage + .getToastTitle(10000) + .should("exist") + .contains( + /Data job Queued for execution|Failed, Data job is already executing/ + ); + }); - dataJobManageDetailsPage - .downloadJobKey(); + it("Data Job Manage Details Page - download job key", () => { + dataJobManageDetailsPage = DataJobManageDetailsPage.navigateTo( + longLivedTestJob.team, + longLivedTestJob.job_name + ); - dataJobManageDetailsPage - .readFile('downloadsFolder', `${ longLivedTestJob.job_name }.keytab`) - .should('exist'); - }); + dataJobManageDetailsPage.openActionDropdown(); - it('Data Job Manage Details Page - delete job', { tags: '@integration' }, () => { - cy.fixture('lib/explore/additional-test-job.json').then((additionalTestJob) => { - const normalizedTestJob = applyGlobalEnvSettings(additionalTestJob); + dataJobManageDetailsPage.downloadJobKey(); - cy.prepareAdditionalTestJobs(); + dataJobManageDetailsPage + .readFile( + "downloadsFolder", + `${longLivedTestJob.job_name}.keytab` + ) + .should("exist"); + }); - dataJobManageDetailsPage = DataJobManageDetailsPage - .navigateTo(normalizedTestJob.team, normalizedTestJob.job_name); + it( + "Data Job Manage Details Page - delete job", + { tags: "@integration" }, + () => { + cy.fixture("lib/explore/additional-test-job.json").then( + (additionalTestJob) => { + const normalizedTestJob = + applyGlobalEnvSettings(additionalTestJob); - dataJobManageDetailsPage.clickOnContentContainer(); + cy.prepareAdditionalTestJobs(); - dataJobManageDetailsPage - .openActionDropdown(); + dataJobManageDetailsPage = + DataJobManageDetailsPage.navigateTo( + normalizedTestJob.team, + normalizedTestJob.job_name + ); - dataJobManageDetailsPage - .deleteJob(); + dataJobManageDetailsPage.clickOnContentContainer(); - dataJobManageDetailsPage - .confirmDeleteJob(); + dataJobManageDetailsPage.openActionDropdown(); - dataJobManageDetailsPage - .getToastTitle(20000) // Wait up to 20 seconds for the job to be deleted. - .should('contain.text', 'Data job delete completed') + dataJobManageDetailsPage.deleteJob(); - dataJobManageDetailsPage - .waitForBackendRequestCompletion(); + dataJobManageDetailsPage.confirmDeleteJob(); - const dataJobsManagePage = DataJobsManagePage - .getPage(); + dataJobManageDetailsPage + .getToastTitle(20000) // Wait up to 20 seconds for the job to be deleted. + .should( + "contain.text", + "Data job delete completed" + ); - dataJobsManagePage - .getDataGridCell(normalizedTestJob.job_name, 10000) // Wait up to 10 seconds for the jobs list to show. - .should('not.exist'); - }); - }); - - //TODO: Double-check and enable this test - it.skip('Data Job Manage Details Page - executions timeline', () => { - const jobName = longLivedTestJob.job_name; - const team = longLivedTestJob.team; - - cy.intercept({ - method: 'GET', - url: `/data-jobs/for-team/${ team }/jobs/${ jobName }/executions` - }).as('executionApiCall') - - dataJobManageDetailsPage = DataJobManageDetailsPage - .navigateTo(team, jobName); - - cy.wait('@executionApiCall').then((interception) => { - const response = interception.response.body; - const lastExecutions = response - .sort((left, right) => compareDatesAsc(left, right)) - .slice(response.length > 5 ? response.length - 5 : 0); - - const lastExecutionsSize = lastExecutions.length; - const lastExecution = lastExecutions.at(-1); - - cy.get('.clr-timeline-step') - .should('have.length', lastExecutionsSize + 1) // +1 next execution - - cy.get(`[data-cy=${ lastExecution.id }]`) - .as('lastExecution') - - let statusIconMap = []; - statusIconMap['cancelled'] = 'times-circle'; - statusIconMap['skipped'] = 'circle-arrow'; - statusIconMap['submitted'] = 'circle'; - statusIconMap['finished'] = 'success-standard'; - statusIconMap['failed'] = 'error-standard'; - - if (lastExecution.type !== 'manual') { - cy.get('@lastExecution') - .find('.manual-execution-label') - .scrollIntoView() - .should('be.visible'); - } + dataJobManageDetailsPage.waitForBackendRequestCompletion(); - if (lastExecution.status !== 'running') { - cy.get('@lastExecution') - .find(`[shape=${ statusIconMap[lastExecution.status] }]`) - .should('exist') - } + const dataJobsManagePage = DataJobsManagePage.getPage(); - cy.get('@lastExecution') - .find('.clr-timeline-step-header') - .invoke('attr', 'title') - .should('contain', 'Started ') - - if (lastExecution.status !== 'running') { - cy.get('@lastExecution') - .find('u') - .last() - .invoke('attr', 'title') - .should('contain', 'Ended ') + dataJobsManagePage + .getDataGridCell(normalizedTestJob.job_name, 10000) // Wait up to 10 seconds for the jobs list to show. + .should("not.exist"); + } + ); } - }) - }) -}); + ); + + //TODO: Double-check and enable this test + it.skip("Data Job Manage Details Page - executions timeline", () => { + const jobName = longLivedTestJob.job_name; + const team = longLivedTestJob.team; + + cy.intercept({ + method: "GET", + url: `/data-jobs/for-team/${team}/jobs/${jobName}/executions`, + }).as("executionApiCall"); + + dataJobManageDetailsPage = DataJobManageDetailsPage.navigateTo( + team, + jobName + ); + + cy.wait("@executionApiCall").then((interception) => { + const response = interception.response.body; + const lastExecutions = response + .sort((left, right) => compareDatesAsc(left, right)) + .slice(response.length > 5 ? response.length - 5 : 0); + + const lastExecutionsSize = lastExecutions.length; + const lastExecution = lastExecutions.at(-1); + + cy.get(".clr-timeline-step").should( + "have.length", + lastExecutionsSize + 1 + ); // +1 next execution + + cy.get(`[data-cy=${lastExecution.id}]`).as("lastExecution"); + + let statusIconMap = []; + statusIconMap["cancelled"] = "times-circle"; + statusIconMap["skipped"] = "circle-arrow"; + statusIconMap["submitted"] = "circle"; + statusIconMap["finished"] = "success-standard"; + statusIconMap["failed"] = "error-standard"; + + if (lastExecution.type !== "manual") { + cy.get("@lastExecution") + .find(".manual-execution-label") + .scrollIntoView() + .should("be.visible"); + } + + if (lastExecution.status !== "running") { + cy.get("@lastExecution") + .find(`[shape=${statusIconMap[lastExecution.status]}]`) + .should("exist"); + } + + cy.get("@lastExecution") + .find(".clr-timeline-step-header") + .invoke("attr", "title") + .should("contain", "Started "); + + if (lastExecution.status !== "running") { + cy.get("@lastExecution") + .find("u") + .last() + .invoke("attr", "title") + .should("contain", "Ended "); + } + }); + }); + } +); diff --git a/projects/frontend/data-pipelines/gui/e2e/integration/lib/manage/data-job-executions.int.spec.js b/projects/frontend/data-pipelines/gui/e2e/integration/lib/manage/data-job-executions.int.spec.js index 20563bbca5..d8a83d3317 100644 --- a/projects/frontend/data-pipelines/gui/e2e/integration/lib/manage/data-job-executions.int.spec.js +++ b/projects/frontend/data-pipelines/gui/e2e/integration/lib/manage/data-job-executions.int.spec.js @@ -5,640 +5,636 @@ /// -import { DataJobBasePO } from '../../../support/application/data-job-base.po'; -import { DataJobsManagePage } from '../../../support/pages/app/lib/manage/data-jobs.po'; -import { DataJobManageExecutionsPage } from '../../../support/pages/app/lib/manage/data-job-executions.po'; -import { applyGlobalEnvSettings } from '../../../support/helpers/commands.helpers'; - -describe('Data Job Manage Executions Page', { tags: ['@dataPipelines', '@manageDataJobExecutions'] }, () => { - let longLivedTestJob; - - before(() => { - return DataJobManageExecutionsPage.recordHarIfSupported() - .then(() => cy.clearLocalStorageSnapshot('data-job-manage-executions')) - .then(() => DataJobManageExecutionsPage.login()) - .then(() => cy.saveLocalStorage('data-job-manage-executions')) - .then(() => cy.prepareLongLivedTestJob()) - .then(() => cy.createTwoExecutionsLongLivedTestJob()) - .then(() => cy.fixture('lib/manage/e2e-cypress-dp-test.json')) - .then((loadedTestJob) => { - longLivedTestJob = applyGlobalEnvSettings(loadedTestJob); - - return cy.wrap({ context: 'manage::data-job-executions.spec::before()', action: 'continue' }); - }); - }); - - after(() => { - DataJobManageExecutionsPage.saveHarIfSupported(); - }); - - beforeEach(() => { - cy.restoreLocalStorage('data-job-manage-executions'); - - DataJobManageExecutionsPage.initBackendRequestInterceptor(); - }); - - describe('Sanity', { tags: '@integration' }, () => { - it(`Data Job Manage Executions Page - should open Details and verify Executions tab is displayed and navigates`, () => { - cy.log('Fixture for name: ' + longLivedTestJob.job_name); - - const dataJobsManagePage = DataJobsManagePage.navigateTo(); - - dataJobsManagePage - .clickOnContentContainer(); - - dataJobsManagePage - .chooseQuickFilter(0); - - dataJobsManagePage - .openJobDetails(longLivedTestJob.team, longLivedTestJob.job_name); - - const dataJobBasePage = DataJobBasePO - .getPage(); - - dataJobBasePage - .getDetailsTab() - .should('exist') - .should('have.class', 'active'); - - dataJobBasePage - .getExecutionsTab() - .should('exist') - .should('not.have.class', 'active'); - - dataJobBasePage - .openExecutionsTab(); - - const dataJobExecutionsPage = DataJobManageExecutionsPage - .getPage(); - - dataJobExecutionsPage - .getDetailsTab() - .should('exist') - .should('not.have.class', 'active'); - - dataJobExecutionsPage - .getExecutionsTab() - .should('exist') - .should('have.class', 'active'); - - dataJobExecutionsPage - .getDataGrid() - .should('exist'); - }); - - it('Data Job Manage Executions Page - should verify on URL navigate to Executions will open the page', () => { - const dataJobExecutionsPage = DataJobManageExecutionsPage - .navigateTo(longLivedTestJob.team, longLivedTestJob.job_name); - - dataJobExecutionsPage - .getCurrentUrl() - .should('match', new RegExp(`\\/manage\\/data-jobs\\/${longLivedTestJob.team}\\/${longLivedTestJob.job_name}\\/executions$`)); - - dataJobExecutionsPage - .getDetailsTab() - .should('exist') - .should('not.have.class', 'active'); - - dataJobExecutionsPage - .getExecutionsTab() - .should('exist') - .should('have.class', 'active'); - - dataJobExecutionsPage - .getDataGrid() - .should('exist'); +import { DataJobBasePO } from "../../../support/application/data-job-base.po"; +import { DataJobsManagePage } from "../../../support/pages/app/lib/manage/data-jobs.po"; +import { DataJobManageExecutionsPage } from "../../../support/pages/app/lib/manage/data-job-executions.po"; +import { applyGlobalEnvSettings } from "../../../support/helpers/commands.helpers"; + +describe( + "Data Job Manage Executions Page", + { tags: ["@dataPipelines", "@manageDataJobExecutions"] }, + () => { + let longLivedTestJob; + + before(() => { + return DataJobManageExecutionsPage.recordHarIfSupported() + .then(() => + cy.clearLocalStorageSnapshot("data-job-manage-executions") + ) + .then(() => DataJobManageExecutionsPage.login()) + .then(() => cy.saveLocalStorage("data-job-manage-executions")) + .then(() => cy.prepareLongLivedTestJob()) + .then(() => cy.createTwoExecutionsLongLivedTestJob()) + .then(() => cy.fixture("lib/manage/e2e-cypress-dp-test.json")) + .then((loadedTestJob) => { + longLivedTestJob = applyGlobalEnvSettings(loadedTestJob); + + return cy.wrap({ + context: "manage::data-job-executions.spec::before()", + action: "continue", + }); + }); }); - it('Data Job Manage Executions Page - should verify elements are rendered in DOM', () => { - const dataJobExecutionsPage = DataJobManageExecutionsPage - .navigateTo(longLivedTestJob.team, longLivedTestJob.job_name); - - dataJobExecutionsPage - .getMainTitle() - .should('be.visible') - .should('contains.text', longLivedTestJob.job_name); - - dataJobExecutionsPage - .getDetailsTab() - .should('exist') - .should('not.have.class', 'active'); - - dataJobExecutionsPage - .getExecutionsTab() - .should('exist') - .should('have.class', 'active'); - - dataJobExecutionsPage - .getExecuteNowButton() - .should('exist'); - - dataJobExecutionsPage - .getActionDropdownBtn() - .should('exist'); - - dataJobExecutionsPage - .openActionDropdown(); - - dataJobExecutionsPage - .getDeleteJobBtn() - .should('exist'); - - dataJobExecutionsPage - .clickOnContentContainer(); - - dataJobExecutionsPage - .waitForSmartDelay(); - - dataJobExecutionsPage - .getTimePeriod() - .should('exist'); - - dataJobExecutionsPage - .getStatusChart() - .should('exist'); - - dataJobExecutionsPage - .getDurationChart() - .should('exist'); - - dataJobExecutionsPage - .getDataGrid() - .should('exist'); - - dataJobExecutionsPage - .getDataGridRows() - .should('have.length.gt', 0); + after(() => { + DataJobManageExecutionsPage.saveHarIfSupported(); }); - it('Data Job Manage Executions Page - should verify cancel execution button works properly', () => { - const dataJobExecutionsPage = DataJobManageExecutionsPage - .navigateTo(longLivedTestJob.team, longLivedTestJob.job_name); - - dataJobExecutionsPage - .initPostExecutionInterceptor(); - dataJobExecutionsPage - .initDeleteExecutionInterceptor(); - dataJobExecutionsPage - .initGetExecutionInterceptor(); - dataJobExecutionsPage - .initGetExecutionsInterceptor(); - - dataJobExecutionsPage - .getExecutionsTab() - .should('exist') - .should('have.class', 'active'); - - // Execute data job and check if the execution status after that is Running or Submitted - dataJobExecutionsPage - .getExecuteNowButton() - .should('exist'); - dataJobExecutionsPage - .executeNow(); - dataJobExecutionsPage - .getConfirmDialogButton() - .should('exist') - .click({ force: true }); - dataJobExecutionsPage - .waitForPostExecutionCompletion(); - dataJobExecutionsPage - .waitForDataJobStartExecute(); - - dataJobExecutionsPage - .waitForViewToRenderShort(); - - dataJobExecutionsPage - .getExecutionStatus() - .first() - .contains(/Running|Submitted/); - - // Cancel data job execution and check if the status after that is Cancelled - dataJobExecutionsPage - .getCancelExecutionButton() - .should('exist') - .click({ force: true }) - dataJobExecutionsPage - .getConfirmDialogButton() - .should('exist') - .click({ force: true }); - dataJobExecutionsPage - .waitForDeleteExecutionCompletion(); - dataJobExecutionsPage - .waitForDataJobStopExecute(); - - dataJobExecutionsPage - .waitForViewToRenderShort(); + beforeEach(() => { + cy.restoreLocalStorage("data-job-manage-executions"); - dataJobExecutionsPage - .getExecutionStatus() - .first() - .should('contains.text', 'Canceled'); + DataJobManageExecutionsPage.initBackendRequestInterceptor(); }); - }); - - it('Data Job Manage Executions Page - should verify time period is in correct format', () => { - const dataJobExecutionsPage = DataJobManageExecutionsPage - .navigateTo(longLivedTestJob.team, longLivedTestJob.job_name); - - dataJobExecutionsPage - .getTimePeriod() - .invoke('text') - .invoke('trim') - .should('match', new RegExp(`^\\w+\\s\\d+,\\s\\d+,\\s\\d+:\\d+:\\d+\\s(AM|PM)\\sto\\s\\w+\\s\\d+,\\s\\d+,\\s\\d+:\\d+:\\d+\\s(AM|PM)$`)); - }); - - it('Data Job Manage Executions Page - should verify refresh button will show spinner and then load data', () => { - const dataJobExecutionsPage = DataJobManageExecutionsPage - .navigateTo(longLivedTestJob.team, longLivedTestJob.job_name); - - dataJobExecutionsPage - .getDataGrid() - .should('exist'); - dataJobExecutionsPage - .getExecLoadingSpinner() - .should('not.exist'); + describe("Sanity", { tags: "@integration" }, () => { + it(`Data Job Manage Executions Page - should open Details and verify Executions tab is displayed and navigates`, () => { + cy.log("Fixture for name: " + longLivedTestJob.job_name); - dataJobExecutionsPage - .getDataGridSpinner() - .should('not.exist'); + const dataJobsManagePage = DataJobsManagePage.navigateTo(); - dataJobExecutionsPage - .waitForActionThinkingTime(); + dataJobsManagePage.clickOnContentContainer(); - dataJobExecutionsPage - .refreshExecData(); + dataJobsManagePage.chooseQuickFilter(0); - dataJobExecutionsPage - .getDataGrid() - .should('exist'); + dataJobsManagePage.openJobDetails( + longLivedTestJob.team, + longLivedTestJob.job_name + ); - dataJobExecutionsPage - .getExecLoadingSpinner() - .should('exist'); + const dataJobBasePage = DataJobBasePO.getPage(); - dataJobExecutionsPage - .getDataGridSpinner() - .should('exist'); + dataJobBasePage + .getDetailsTab() + .should("exist") + .should("have.class", "active"); - dataJobExecutionsPage - .waitForBackendRequestCompletion(); + dataJobBasePage + .getExecutionsTab() + .should("exist") + .should("not.have.class", "active"); - dataJobExecutionsPage - .waitForViewToRender(); + dataJobBasePage.openExecutionsTab(); - dataJobExecutionsPage - .getDataGrid() - .should('exist'); + const dataJobExecutionsPage = + DataJobManageExecutionsPage.getPage(); - dataJobExecutionsPage - .getExecLoadingSpinner() - .should('not.exist'); + dataJobExecutionsPage + .getDetailsTab() + .should("exist") + .should("not.have.class", "active"); - dataJobExecutionsPage - .getDataGridSpinner() - .should('not.exist'); - }); + dataJobExecutionsPage + .getExecutionsTab() + .should("exist") + .should("have.class", "active"); - describe('DataGrid Filters', () => { - it('Data Job Manage Executions Page - should verify status filter options are rendered', () => { - const dataJobExecutionsPage = DataJobManageExecutionsPage - .navigateTo(longLivedTestJob.team, longLivedTestJob.job_name); + dataJobExecutionsPage.getDataGrid().should("exist"); + }); - dataJobExecutionsPage - .openStatusFilter(); - - dataJobExecutionsPage - .getDataGridPopupFilter() - .should('exist'); - - dataJobExecutionsPage - .getDataGridExecStatusFilters() - .then((elements) => Array.from(elements).map((el) => el.innerText)) - .should('deep.equal', ['Success', 'Platform Error', 'User Error', 'Running', 'Submitted', 'Skipped', 'Canceled']); + it("Data Job Manage Executions Page - should verify on URL navigate to Executions will open the page", () => { + const dataJobExecutionsPage = + DataJobManageExecutionsPage.navigateTo( + longLivedTestJob.team, + longLivedTestJob.job_name + ); - dataJobExecutionsPage - .closeFilter(); + dataJobExecutionsPage + .getCurrentUrl() + .should( + "match", + new RegExp( + `\\/manage\\/data-jobs\\/${longLivedTestJob.team}\\/${longLivedTestJob.job_name}\\/executions$` + ) + ); - dataJobExecutionsPage - .getDataGridPopupFilter() - .should('not.exist'); + dataJobExecutionsPage + .getDetailsTab() + .should("exist") + .should("not.have.class", "active"); + + dataJobExecutionsPage + .getExecutionsTab() + .should("exist") + .should("have.class", "active"); + + dataJobExecutionsPage.getDataGrid().should("exist"); + }); + + it("Data Job Manage Executions Page - should verify elements are rendered in DOM", () => { + const dataJobExecutionsPage = + DataJobManageExecutionsPage.navigateTo( + longLivedTestJob.team, + longLivedTestJob.job_name + ); + + dataJobExecutionsPage + .getMainTitle() + .should("be.visible") + .should("contains.text", longLivedTestJob.job_name); + + dataJobExecutionsPage + .getDetailsTab() + .should("exist") + .should("not.have.class", "active"); + + dataJobExecutionsPage + .getExecutionsTab() + .should("exist") + .should("have.class", "active"); + + dataJobExecutionsPage.getExecuteNowButton().should("exist"); + + dataJobExecutionsPage.getActionDropdownBtn().should("exist"); + + dataJobExecutionsPage.openActionDropdown(); + + dataJobExecutionsPage.getDeleteJobBtn().should("exist"); + + dataJobExecutionsPage.clickOnContentContainer(); + + dataJobExecutionsPage.waitForSmartDelay(); + + dataJobExecutionsPage.getTimePeriod().should("exist"); + + dataJobExecutionsPage.getStatusChart().should("exist"); + + dataJobExecutionsPage.getDurationChart().should("exist"); + + dataJobExecutionsPage.getDataGrid().should("exist"); + + dataJobExecutionsPage + .getDataGridRows() + .should("have.length.gt", 0); + }); + + it("Data Job Manage Executions Page - should verify cancel execution button works properly", () => { + const dataJobExecutionsPage = + DataJobManageExecutionsPage.navigateTo( + longLivedTestJob.team, + longLivedTestJob.job_name + ); + + dataJobExecutionsPage.initPostExecutionInterceptor(); + dataJobExecutionsPage.initDeleteExecutionInterceptor(); + dataJobExecutionsPage.initGetExecutionInterceptor(); + dataJobExecutionsPage.initGetExecutionsInterceptor(); + + dataJobExecutionsPage + .getExecutionsTab() + .should("exist") + .should("have.class", "active"); + + // Execute data job and check if the execution status after that is Running or Submitted + dataJobExecutionsPage.getExecuteNowButton().should("exist"); + dataJobExecutionsPage.executeNow(); + dataJobExecutionsPage + .getConfirmDialogButton() + .should("exist") + .click({ force: true }); + dataJobExecutionsPage.waitForPostExecutionCompletion(); + dataJobExecutionsPage.waitForDataJobStartExecute(); + + dataJobExecutionsPage.waitForViewToRenderShort(); + + dataJobExecutionsPage + .getExecutionStatus() + .first() + .contains(/Running|Submitted/); + + // Cancel data job execution and check if the status after that is Cancelled + dataJobExecutionsPage + .getCancelExecutionButton() + .should("exist") + .click({ force: true }); + dataJobExecutionsPage + .getConfirmDialogButton() + .should("exist") + .click({ force: true }); + dataJobExecutionsPage.waitForDeleteExecutionCompletion(); + dataJobExecutionsPage.waitForDataJobStopExecute(); + + dataJobExecutionsPage.waitForViewToRenderShort(); + + dataJobExecutionsPage + .getExecutionStatus() + .first() + .should("contains.text", "Canceled"); + }); }); - it('Data Job Manage Executions Page - should verify type filter options are rendered', () => { - const dataJobExecutionsPage = DataJobManageExecutionsPage - .navigateTo(longLivedTestJob.team, longLivedTestJob.job_name); - - dataJobExecutionsPage - .openTypeFilter(); - - dataJobExecutionsPage - .getDataGridPopupFilter() - .should('exist'); - - dataJobExecutionsPage - .getDataGridExecTypeFilters() - .then((elements) => Array.from(elements).map((el) => el.innerText)) - .should('deep.equal', ['Manual', 'Scheduled']); - - dataJobExecutionsPage - .closeFilter(); + it("Data Job Manage Executions Page - should verify time period is in correct format", () => { + const dataJobExecutionsPage = + DataJobManageExecutionsPage.navigateTo( + longLivedTestJob.team, + longLivedTestJob.job_name + ); dataJobExecutionsPage - .getDataGridPopupFilter() - .should('not.exist'); + .getTimePeriod() + .invoke("text") + .invoke("trim") + .should( + "match", + new RegExp( + `^\\w+\\s\\d+,\\s\\d+,\\s\\d+:\\d+:\\d+\\s(AM|PM)\\sto\\s\\w+\\s\\d+,\\s\\d+,\\s\\d+:\\d+:\\d+\\s(AM|PM)$` + ) + ); }); - it('Data Job Manage Executions Page - should verify id filter render input and filters correctly', () => { - const dataJobExecutionsPage = DataJobManageExecutionsPage - .navigateTo(longLivedTestJob.team, longLivedTestJob.job_name); - - dataJobExecutionsPage - .getDataGridRows() - .should('have.length.gt', 0); - - dataJobExecutionsPage - .openIDFilter(); - - dataJobExecutionsPage - .getDataGridPopupFilter() - .should('exist'); + it("Data Job Manage Executions Page - should verify refresh button will show spinner and then load data", () => { + const dataJobExecutionsPage = + DataJobManageExecutionsPage.navigateTo( + longLivedTestJob.team, + longLivedTestJob.job_name + ); - dataJobExecutionsPage - .typeToFilterInput('xyxyxy'); + dataJobExecutionsPage.getDataGrid().should("exist"); - dataJobExecutionsPage - .getDataGridRows() - .should('have.length', 0); + dataJobExecutionsPage.getExecLoadingSpinner().should("not.exist"); - dataJobExecutionsPage - .clearFilterInput(); + dataJobExecutionsPage.getDataGridSpinner().should("not.exist"); - dataJobExecutionsPage - .getDataGridRows() - .should('have.length.gt', 0); + dataJobExecutionsPage.waitForActionThinkingTime(); - dataJobExecutionsPage - .closeFilter(); + dataJobExecutionsPage.refreshExecData(); - dataJobExecutionsPage - .getDataGridPopupFilter() - .should('not.exist'); - }); + dataJobExecutionsPage.getDataGrid().should("exist"); - it('Data Job Manage Executions Page - should verify version filter render input and filters correctly', () => { - const dataJobExecutionsPage = DataJobManageExecutionsPage - .navigateTo(longLivedTestJob.team, longLivedTestJob.job_name); + dataJobExecutionsPage.getExecLoadingSpinner().should("exist"); - dataJobExecutionsPage - .getDataGridRows() - .should('have.length.gt', 0); + dataJobExecutionsPage.getDataGridSpinner().should("exist"); - dataJobExecutionsPage - .openVersionFilter(); + dataJobExecutionsPage.waitForBackendRequestCompletion(); - dataJobExecutionsPage - .getDataGridPopupFilter() - .should('exist'); + dataJobExecutionsPage.waitForViewToRender(); - dataJobExecutionsPage - .typeToFilterInput('xyxyxy'); + dataJobExecutionsPage.getDataGrid().should("exist"); - dataJobExecutionsPage - .getDataGridRows() - .should('have.length', 0); + dataJobExecutionsPage.getExecLoadingSpinner().should("not.exist"); - dataJobExecutionsPage - .clearFilterInput(); + dataJobExecutionsPage.getDataGridSpinner().should("not.exist"); + }); - dataJobExecutionsPage - .getDataGridRows() - .should('have.length.gt', 0); + describe("DataGrid Filters", () => { + it("Data Job Manage Executions Page - should verify status filter options are rendered", () => { + const dataJobExecutionsPage = + DataJobManageExecutionsPage.navigateTo( + longLivedTestJob.team, + longLivedTestJob.job_name + ); - dataJobExecutionsPage - .closeFilter(); + dataJobExecutionsPage.openStatusFilter(); - dataJobExecutionsPage - .getDataGridPopupFilter() - .should('not.exist'); - }); - }); + dataJobExecutionsPage.getDataGridPopupFilter().should("exist"); - describe('DataGrid Sort', () => { - it('Data Job Manage Executions Page - should verify duration sort works', () => { - const dataJobExecutionsPage = DataJobManageExecutionsPage - .navigateTo(longLivedTestJob.team, longLivedTestJob.job_name); + dataJobExecutionsPage + .getDataGridExecStatusFilters() + .then((elements) => + Array.from(elements).map((el) => el.innerText) + ) + .should("deep.equal", [ + "Success", + "Platform Error", + "User Error", + "Running", + "Submitted", + "Skipped", + "Canceled", + ]); - dataJobExecutionsPage - .getDataGridRows() - .should('have.length.gt', 0); + dataJobExecutionsPage.closeFilter(); - dataJobExecutionsPage - .getDataGridExecDurationHeader() - .should('exist') - .invoke('attr', 'aria-sort') - .should('eq', 'none'); + dataJobExecutionsPage + .getDataGridPopupFilter() + .should("not.exist"); + }); - dataJobExecutionsPage - .sortByExecDuration(); + it("Data Job Manage Executions Page - should verify type filter options are rendered", () => { + const dataJobExecutionsPage = + DataJobManageExecutionsPage.navigateTo( + longLivedTestJob.team, + longLivedTestJob.job_name + ); - dataJobExecutionsPage - .getDataGridExecDurationHeader() - .should('exist') - .invoke('attr', 'aria-sort') - .should('eq', 'ascending'); + dataJobExecutionsPage.openTypeFilter(); - dataJobExecutionsPage - .getDataGridRows() - .should('have.length.gt', 0); + dataJobExecutionsPage.getDataGridPopupFilter().should("exist"); - dataJobExecutionsPage - .getDataGridExecDurationCell(1) - .invoke('text') - .invoke('trim') - .then((elText1) => { - return dataJobExecutionsPage - .getDataGridExecDurationCell(2) - .invoke('text') - .invoke('trim') - .then((elText2) => { - return dataJobExecutionsPage.convertStringContentToSeconds(elText1) - - dataJobExecutionsPage.convertStringContentToSeconds(elText2); - }); - }) - .should('be.lte', 0); + dataJobExecutionsPage + .getDataGridExecTypeFilters() + .then((elements) => + Array.from(elements).map((el) => el.innerText) + ) + .should("deep.equal", ["Manual", "Scheduled"]); - dataJobExecutionsPage - .sortByExecDuration(); + dataJobExecutionsPage.closeFilter(); - dataJobExecutionsPage - .getDataGridExecDurationHeader() - .should('exist') - .invoke('attr', 'aria-sort') - .should('eq', 'descending'); + dataJobExecutionsPage + .getDataGridPopupFilter() + .should("not.exist"); + }); - dataJobExecutionsPage - .getDataGridRows() - .should('have.length.gt', 0); + it("Data Job Manage Executions Page - should verify id filter render input and filters correctly", () => { + const dataJobExecutionsPage = + DataJobManageExecutionsPage.navigateTo( + longLivedTestJob.team, + longLivedTestJob.job_name + ); - dataJobExecutionsPage - .getDataGridExecDurationCell(1) - .invoke('text') - .invoke('trim') - .then((elText1) => { - return dataJobExecutionsPage - .getDataGridExecDurationCell(2) - .invoke('text') - .invoke('trim') - .then((elText2) => { - return dataJobExecutionsPage.convertStringContentToSeconds(elText1) - - dataJobExecutionsPage.convertStringContentToSeconds(elText2); - }); - }) - .should('be.gte', 0); - }); + dataJobExecutionsPage + .getDataGridRows() + .should("have.length.gt", 0); - it('Data Job Manage Executions Page - should verify execution start sort works', () => { - const dataJobExecutionsPage = DataJobManageExecutionsPage - .navigateTo(longLivedTestJob.team, longLivedTestJob.job_name); + dataJobExecutionsPage.openIDFilter(); - dataJobExecutionsPage - .getDataGridRows() - .should('have.length.gt', 0); + dataJobExecutionsPage.getDataGridPopupFilter().should("exist"); - dataJobExecutionsPage - .getDataGridExecStartHeader() - .should('exist') - .invoke('attr', 'aria-sort') - .should('eq', 'descending'); + dataJobExecutionsPage.typeToFilterInput("xyxyxy"); - dataJobExecutionsPage - .getDataGridExecStartCell(1) - .invoke('text') - .invoke('trim') - .then((elText1) => { - return dataJobExecutionsPage - .getDataGridExecStartCell(2) - .invoke('text') - .invoke('trim') - .then((elText2) => { - return new Date(elText1) - new Date(elText2) - }); - }) - .should('be.gte', 0); + dataJobExecutionsPage + .getDataGridRows() + .should("have.length", 0); - dataJobExecutionsPage - .sortByExecStart(); + dataJobExecutionsPage.clearFilterInput(); - dataJobExecutionsPage - .getDataGridExecStartHeader() - .should('exist') - .invoke('attr', 'aria-sort') - .should('eq', 'ascending'); + dataJobExecutionsPage + .getDataGridRows() + .should("have.length.gt", 0); - dataJobExecutionsPage - .getDataGridRows() - .should('have.length.gt', 0); + dataJobExecutionsPage.closeFilter(); - dataJobExecutionsPage - .getDataGridExecStartCell(1) - .invoke('text') - .invoke('trim') - .then((elText1) => { - return dataJobExecutionsPage - .getDataGridExecStartCell(2) - .invoke('text') - .invoke('trim') - .then((elText2) => { - return new Date(elText1) - new Date(elText2) - }); - }) - .should('be.lte', 0); - }); + dataJobExecutionsPage + .getDataGridPopupFilter() + .should("not.exist"); + }); - it('Data Job Manage Executions Page - should verify execution end sort works', () => { - const dataJobExecutionsPage = DataJobManageExecutionsPage - .navigateTo(longLivedTestJob.team, longLivedTestJob.job_name); + it("Data Job Manage Executions Page - should verify version filter render input and filters correctly", () => { + const dataJobExecutionsPage = + DataJobManageExecutionsPage.navigateTo( + longLivedTestJob.team, + longLivedTestJob.job_name + ); - dataJobExecutionsPage - .getDataGridRows() - .should('have.length.gt', 0); + dataJobExecutionsPage + .getDataGridRows() + .should("have.length.gt", 0); - dataJobExecutionsPage - .getDataGridExecEndHeader() - .should('exist') - .invoke('attr', 'aria-sort') - .should('eq', 'none'); + dataJobExecutionsPage.openVersionFilter(); - dataJobExecutionsPage - .sortByExecEnd(); + dataJobExecutionsPage.getDataGridPopupFilter().should("exist"); - dataJobExecutionsPage - .getDataGridExecEndHeader() - .should('exist') - .invoke('attr', 'aria-sort') - .should('eq', 'ascending'); + dataJobExecutionsPage.typeToFilterInput("xyxyxy"); - dataJobExecutionsPage - .getDataGridRows() - .should('have.length.gt', 0); + dataJobExecutionsPage + .getDataGridRows() + .should("have.length", 0); - dataJobExecutionsPage - .getDataGridExecEndCell(1) - .invoke('text') - .invoke('trim') - .then((elText1) => { - return dataJobExecutionsPage - .getDataGridExecEndCell(2) - .invoke('text') - .invoke('trim') - .then((elText2) => { - const d1 = elText1 - ? new Date(elText1) - : new Date(); - const d2 = elText2 - ? new Date(elText2) - : new Date(); - - return d1 - d2 - }); - }) - .should('be.lte', 0); + dataJobExecutionsPage.clearFilterInput(); - dataJobExecutionsPage - .sortByExecEnd(); + dataJobExecutionsPage + .getDataGridRows() + .should("have.length.gt", 0); - dataJobExecutionsPage - .getDataGridExecEndHeader() - .should('exist') - .invoke('attr', 'aria-sort') - .should('eq', 'descending'); + dataJobExecutionsPage.closeFilter(); - dataJobExecutionsPage - .getDataGridRows() - .should('have.length.gt', 0); + dataJobExecutionsPage + .getDataGridPopupFilter() + .should("not.exist"); + }); + }); - dataJobExecutionsPage - .getDataGridExecEndCell(1) - .invoke('text') - .invoke('trim') - .then((elText1) => { - return dataJobExecutionsPage - .getDataGridExecEndCell(2) - .invoke('text') - .invoke('trim') - .then((elText2) => { - const d1 = elText1 - ? new Date(elText1) - : new Date(); - const d2 = elText2 - ? new Date(elText2) - : new Date(); - - return d1 - d2 - }); - }) - .should('be.gte', 0); + describe("DataGrid Sort", () => { + it("Data Job Manage Executions Page - should verify duration sort works", () => { + const dataJobExecutionsPage = + DataJobManageExecutionsPage.navigateTo( + longLivedTestJob.team, + longLivedTestJob.job_name + ); + + dataJobExecutionsPage + .getDataGridRows() + .should("have.length.gt", 0); + + dataJobExecutionsPage + .getDataGridExecDurationHeader() + .should("exist") + .invoke("attr", "aria-sort") + .should("eq", "none"); + + dataJobExecutionsPage.sortByExecDuration(); + + dataJobExecutionsPage + .getDataGridExecDurationHeader() + .should("exist") + .invoke("attr", "aria-sort") + .should("eq", "ascending"); + + dataJobExecutionsPage + .getDataGridRows() + .should("have.length.gt", 0); + + dataJobExecutionsPage + .getDataGridExecDurationCell(1) + .invoke("text") + .invoke("trim") + .then((elText1) => { + return dataJobExecutionsPage + .getDataGridExecDurationCell(2) + .invoke("text") + .invoke("trim") + .then((elText2) => { + return ( + dataJobExecutionsPage.convertStringContentToSeconds( + elText1 + ) - + dataJobExecutionsPage.convertStringContentToSeconds( + elText2 + ) + ); + }); + }) + .should("be.lte", 0); + + dataJobExecutionsPage.sortByExecDuration(); + + dataJobExecutionsPage + .getDataGridExecDurationHeader() + .should("exist") + .invoke("attr", "aria-sort") + .should("eq", "descending"); + + dataJobExecutionsPage + .getDataGridRows() + .should("have.length.gt", 0); + + dataJobExecutionsPage + .getDataGridExecDurationCell(1) + .invoke("text") + .invoke("trim") + .then((elText1) => { + return dataJobExecutionsPage + .getDataGridExecDurationCell(2) + .invoke("text") + .invoke("trim") + .then((elText2) => { + return ( + dataJobExecutionsPage.convertStringContentToSeconds( + elText1 + ) - + dataJobExecutionsPage.convertStringContentToSeconds( + elText2 + ) + ); + }); + }) + .should("be.gte", 0); + }); + + it("Data Job Manage Executions Page - should verify execution start sort works", () => { + const dataJobExecutionsPage = + DataJobManageExecutionsPage.navigateTo( + longLivedTestJob.team, + longLivedTestJob.job_name + ); + + dataJobExecutionsPage + .getDataGridRows() + .should("have.length.gt", 0); + + dataJobExecutionsPage + .getDataGridExecStartHeader() + .should("exist") + .invoke("attr", "aria-sort") + .should("eq", "descending"); + + dataJobExecutionsPage + .getDataGridExecStartCell(1) + .invoke("text") + .invoke("trim") + .then((elText1) => { + return dataJobExecutionsPage + .getDataGridExecStartCell(2) + .invoke("text") + .invoke("trim") + .then((elText2) => { + return new Date(elText1) - new Date(elText2); + }); + }) + .should("be.gte", 0); + + dataJobExecutionsPage.sortByExecStart(); + + dataJobExecutionsPage + .getDataGridExecStartHeader() + .should("exist") + .invoke("attr", "aria-sort") + .should("eq", "ascending"); + + dataJobExecutionsPage + .getDataGridRows() + .should("have.length.gt", 0); + + dataJobExecutionsPage + .getDataGridExecStartCell(1) + .invoke("text") + .invoke("trim") + .then((elText1) => { + return dataJobExecutionsPage + .getDataGridExecStartCell(2) + .invoke("text") + .invoke("trim") + .then((elText2) => { + return new Date(elText1) - new Date(elText2); + }); + }) + .should("be.lte", 0); + }); + + it("Data Job Manage Executions Page - should verify execution end sort works", () => { + const dataJobExecutionsPage = + DataJobManageExecutionsPage.navigateTo( + longLivedTestJob.team, + longLivedTestJob.job_name + ); + + dataJobExecutionsPage + .getDataGridRows() + .should("have.length.gt", 0); + + dataJobExecutionsPage + .getDataGridExecEndHeader() + .should("exist") + .invoke("attr", "aria-sort") + .should("eq", "none"); + + dataJobExecutionsPage.sortByExecEnd(); + + dataJobExecutionsPage + .getDataGridExecEndHeader() + .should("exist") + .invoke("attr", "aria-sort") + .should("eq", "ascending"); + + dataJobExecutionsPage + .getDataGridRows() + .should("have.length.gt", 0); + + dataJobExecutionsPage + .getDataGridExecEndCell(1) + .invoke("text") + .invoke("trim") + .then((elText1) => { + return dataJobExecutionsPage + .getDataGridExecEndCell(2) + .invoke("text") + .invoke("trim") + .then((elText2) => { + const d1 = elText1 + ? new Date(elText1) + : new Date(); + const d2 = elText2 + ? new Date(elText2) + : new Date(); + + return d1 - d2; + }); + }) + .should("be.lte", 0); + + dataJobExecutionsPage.sortByExecEnd(); + + dataJobExecutionsPage + .getDataGridExecEndHeader() + .should("exist") + .invoke("attr", "aria-sort") + .should("eq", "descending"); + + dataJobExecutionsPage + .getDataGridRows() + .should("have.length.gt", 0); + + dataJobExecutionsPage + .getDataGridExecEndCell(1) + .invoke("text") + .invoke("trim") + .then((elText1) => { + return dataJobExecutionsPage + .getDataGridExecEndCell(2) + .invoke("text") + .invoke("trim") + .then((elText2) => { + const d1 = elText1 + ? new Date(elText1) + : new Date(); + const d2 = elText2 + ? new Date(elText2) + : new Date(); + + return d1 - d2; + }); + }) + .should("be.gte", 0); + }); }); - }); -}); + } +); diff --git a/projects/frontend/data-pipelines/gui/e2e/integration/lib/manage/data-jobs.int.spec.js b/projects/frontend/data-pipelines/gui/e2e/integration/lib/manage/data-jobs.int.spec.js index 9fd6c538a6..9e9c5639dd 100644 --- a/projects/frontend/data-pipelines/gui/e2e/integration/lib/manage/data-jobs.int.spec.js +++ b/projects/frontend/data-pipelines/gui/e2e/integration/lib/manage/data-jobs.int.spec.js @@ -8,487 +8,546 @@ // 1. Is search working // When you click on details does a modal pop-up? -import { DataJobsManagePage } from '../../../support/pages/app/lib/manage/data-jobs.po'; -import { DataJobManageDetailsPage } from '../../../support/pages/app/lib/manage/data-job-details.po'; -import { applyGlobalEnvSettings } from '../../../support/helpers/commands.helpers'; - -describe('Data Jobs Manage Page', { tags: ['@dataPipelines', '@manageDataJobs'] }, () => { - const descriptionWordsBeforeTruncate = 12; - - /** - * @type {DataJobsManagePage} - */ - let dataJobsManagePage; - let testJobs; - let longLivedTestJob; - let longLivedFailingTestJob; - - before(() => { - return DataJobsManagePage.recordHarIfSupported() - .then(() => cy.clearLocalStorageSnapshot('data-jobs-manage')) - .then(() => DataJobsManagePage.login()) - .then(() => cy.saveLocalStorage('data-jobs-manage')) - .then(() => cy.cleanTestJobs()) - .then(() => cy.prepareBaseTestJobs()) - .then(() => cy.prepareLongLivedTestJob()) - .then(() => cy.createTwoExecutionsLongLivedTestJob()) - .then(() => cy.prepareLongLivedFailingTestJob()) - .then(() => - cy.fixture('lib/explore/test-jobs.json') - .then((loadedTestJobs) => { - testJobs = applyGlobalEnvSettings(loadedTestJobs); - - return cy.wrap({ context: 'manage::1::data-jobs.int.spec::before()', action: 'continue' }); - }) - ) - .then(() => - cy.fixture('lib/manage/e2e-cypress-dp-test.json') - .then((loadedTestJob) => { - longLivedTestJob = applyGlobalEnvSettings(loadedTestJob); - - return cy.wrap({ context: 'manage::2::data-jobs.int.spec::before()', action: 'continue' }); - }) - ) - .then(() => - cy.fixture('e2e-cy-dp-failing.job.json') - .then((failingTestJob) => { - longLivedFailingTestJob = applyGlobalEnvSettings(failingTestJob); - - return cy.wrap({ context: 'manage::3::data-jobs.int.spec::before()', action: 'continue' }); - }) - ) - .then(() => - // Enable data job after job end - DataJobsManagePage.changeJobStatus(longLivedTestJob.team, longLivedTestJob.job_name, true) - ); - }); - - beforeEach(() => { - cy.restoreLocalStorage('data-jobs-manage'); - - DataJobsManagePage.initBackendRequestInterceptor(); - - dataJobsManagePage = DataJobsManagePage.navigateTo(); - }); - - after(() => { - cy.cleanTestJobs(); - - // Enable data job after job end - DataJobsManagePage.changeJobStatus(longLivedTestJob.team, longLivedTestJob.job_name, true) - - DataJobsManagePage.saveHarIfSupported(); - }); - - it('Data Jobs Manage Page - loads title', () => { - dataJobsManagePage - .getPageTitle() - .should('be.visible'); - }); - - it('Data Jobs Manage Page - grid contains test jobs', () => { - dataJobsManagePage - .chooseQuickFilter(0); - - dataJobsManagePage - .sortByJobName(); - - dataJobsManagePage - .getDataGrid() - .should('be.visible'); - - testJobs.forEach((testJob) => { - cy.log('Fixture for name: ' + testJob.job_name); +import { DataJobsManagePage } from "../../../support/pages/app/lib/manage/data-jobs.po"; +import { DataJobManageDetailsPage } from "../../../support/pages/app/lib/manage/data-job-details.po"; +import { applyGlobalEnvSettings } from "../../../support/helpers/commands.helpers"; + +describe( + "Data Jobs Manage Page", + { tags: ["@dataPipelines", "@manageDataJobs"] }, + () => { + const descriptionWordsBeforeTruncate = 12; + + /** + * @type {DataJobsManagePage} + */ + let dataJobsManagePage; + let testJobs; + let longLivedTestJob; + let longLivedFailingTestJob; + + before(() => { + return DataJobsManagePage.recordHarIfSupported() + .then(() => cy.clearLocalStorageSnapshot("data-jobs-manage")) + .then(() => DataJobsManagePage.login()) + .then(() => cy.saveLocalStorage("data-jobs-manage")) + .then(() => cy.cleanTestJobs()) + .then(() => cy.prepareBaseTestJobs()) + .then(() => cy.prepareLongLivedTestJob()) + .then(() => cy.createTwoExecutionsLongLivedTestJob()) + .then(() => cy.prepareLongLivedFailingTestJob()) + .then(() => + cy + .fixture("lib/explore/test-jobs.json") + .then((loadedTestJobs) => { + testJobs = applyGlobalEnvSettings(loadedTestJobs); + + return cy.wrap({ + context: + "manage::1::data-jobs.int.spec::before()", + action: "continue", + }); + }) + ) + .then(() => + cy + .fixture("lib/manage/e2e-cypress-dp-test.json") + .then((loadedTestJob) => { + longLivedTestJob = + applyGlobalEnvSettings(loadedTestJob); + + return cy.wrap({ + context: + "manage::2::data-jobs.int.spec::before()", + action: "continue", + }); + }) + ) + .then(() => + cy + .fixture("e2e-cy-dp-failing.job.json") + .then((failingTestJob) => { + longLivedFailingTestJob = + applyGlobalEnvSettings(failingTestJob); + + return cy.wrap({ + context: + "manage::3::data-jobs.int.spec::before()", + action: "continue", + }); + }) + ) + .then(() => + // Enable data job after job end + DataJobsManagePage.changeJobStatus( + longLivedTestJob.team, + longLivedTestJob.job_name, + true + ) + ); + }); + + beforeEach(() => { + cy.restoreLocalStorage("data-jobs-manage"); + + DataJobsManagePage.initBackendRequestInterceptor(); + + dataJobsManagePage = DataJobsManagePage.navigateTo(); + }); + + after(() => { + cy.cleanTestJobs(); + + // Enable data job after job end + DataJobsManagePage.changeJobStatus( + longLivedTestJob.team, + longLivedTestJob.job_name, + true + ); + + DataJobsManagePage.saveHarIfSupported(); + }); + + it("Data Jobs Manage Page - loads title", () => { + dataJobsManagePage.getPageTitle().should("be.visible"); + }); + + it("Data Jobs Manage Page - grid contains test jobs", () => { + dataJobsManagePage.chooseQuickFilter(0); + + dataJobsManagePage.sortByJobName(); + + dataJobsManagePage.getDataGrid().should("be.visible"); + + testJobs.forEach((testJob) => { + cy.log("Fixture for name: " + testJob.job_name); + + dataJobsManagePage + .getDataGridCell(testJob.job_name) + .scrollIntoView() + .should("be.visible"); + }); + }); + + it( + "Data Jobs Manage Page - grid filter by job name", + { tags: "@integration" }, + () => { + dataJobsManagePage.chooseQuickFilter(0); + + dataJobsManagePage.filterByJobName(testJobs[0].job_name); + + dataJobsManagePage + .getDataGridCell(testJobs[0].job_name) + .should("be.visible"); + + dataJobsManagePage + .getDataGridCell(testJobs[1].job_name) + .should("not.exist"); + } + ); + + it( + "Data Jobs Manage Page - grid search by job name", + { tags: "@integration" }, + () => { + dataJobsManagePage.clickOnContentContainer(); + + dataJobsManagePage.chooseQuickFilter(0); + dataJobsManagePage.searchByJobName(testJobs[1].job_name); + + dataJobsManagePage + .getDataGridCell(testJobs[0].job_name) + .should("not.exist"); + + dataJobsManagePage + .getDataGridCell(testJobs[1].job_name) + .should("be.visible"); + } + ); + + it("Data Jobs Manage Page - grid search parameter goes into URL", () => { + dataJobsManagePage.chooseQuickFilter(0); + + dataJobsManagePage.sortByJobName(); + + // verify 2 test rows visible dataJobsManagePage - .getDataGridCell(testJob.job_name) + .getDataGridCell(testJobs[0].job_name) + .scrollIntoView() + .should("be.visible"); + dataJobsManagePage + .getDataGridCell(testJobs[1].job_name) .scrollIntoView() - .should('be.visible'); - }) - }); - - it('Data Jobs Manage Page - grid filter by job name', { tags: '@integration' }, () => { - dataJobsManagePage - .chooseQuickFilter(0); - - dataJobsManagePage - .filterByJobName(testJobs[0].job_name); - - dataJobsManagePage - .getDataGridCell(testJobs[0].job_name) - .should('be.visible'); - - dataJobsManagePage - .getDataGridCell(testJobs[1].job_name) - .should('not.exist'); - }); - - it('Data Jobs Manage Page - grid search by job name', { tags: '@integration' }, () => { - dataJobsManagePage - .clickOnContentContainer(); - - dataJobsManagePage - .chooseQuickFilter(0); - - dataJobsManagePage - .searchByJobName(testJobs[1].job_name); - - dataJobsManagePage - .getDataGridCell(testJobs[0].job_name) - .should('not.exist'); - - dataJobsManagePage - .getDataGridCell(testJobs[1].job_name) - .should('be.visible'); - }); - - it('Data Jobs Manage Page - grid search parameter goes into URL', () => { - dataJobsManagePage - .chooseQuickFilter(0); - - dataJobsManagePage - .sortByJobName(); - - // verify 2 test rows visible - dataJobsManagePage - .getDataGridCell(testJobs[0].job_name) - .scrollIntoView() - .should('be.visible'); - dataJobsManagePage - .getDataGridCell(testJobs[1].job_name) - .scrollIntoView() - .should('be.visible'); - - // do search - dataJobsManagePage - .searchByJobName(testJobs[0].job_name); - - dataJobsManagePage - .waitForViewToRender(); - - // verify 1 test row visible - dataJobsManagePage - .getDataGridCell(testJobs[0].job_name) - .scrollIntoView() - .should('be.visible'); - dataJobsManagePage - .getDataGridCell(testJobs[1].job_name) - .should('not.exist'); - - // verify url contains search value - dataJobsManagePage - .getCurrentUrl() - .should('match', new RegExp(`\\/manage\\/data-jobs\\?search=${ testJobs[0].job_name }$`)); - - // clear search with clear() method - dataJobsManagePage - .clearSearchField(); - - dataJobsManagePage - .waitForViewToRender(); - - // verify 2 test rows visible - dataJobsManagePage - .getDataGridCell(testJobs[0].job_name) - .scrollIntoView() - .should('be.visible'); - dataJobsManagePage - .getDataGridCell(testJobs[1].job_name) - .scrollIntoView() - .should('be.visible'); - - // verify url does not contain search value - dataJobsManagePage - .getCurrentUrl() - .should('match', new RegExp(`\\/manage\\/data-jobs$`)); - }); - - it('Data Jobs Manage Page - grid search perform search when URL contains search parameter', () => { - // navigate with search value in URL - dataJobsManagePage = DataJobsManagePage.navigateToUrl(`/manage/data-jobs?search=${ testJobs[1].job_name }`); - - dataJobsManagePage - .chooseQuickFilter(0); - - dataJobsManagePage - .sortByJobName(); - - // verify url contains search value - dataJobsManagePage - .getCurrentUrl() - .should('match', new RegExp(`\\/manage\\/data-jobs\\?search=${ testJobs[1].job_name }$`)); - - // verify 1 test row visible - dataJobsManagePage - .getDataGridCell(testJobs[0].job_name) - .should('not.exist'); - dataJobsManagePage - .getDataGridCell(testJobs[1].job_name) - .scrollIntoView() - .should('be.visible'); - - // clear search with button - dataJobsManagePage - .clearSearchFieldWithButton(); - - // verify 2 test rows visible - dataJobsManagePage - .getDataGridCell(testJobs[0].job_name) - .scrollIntoView() - .should('be.visible'); - dataJobsManagePage - .getDataGridCell(testJobs[1].job_name) - .scrollIntoView() - .should('be.visible'); - - // verify url does not contain search value - dataJobsManagePage - .getCurrentUrl() - .should('match', new RegExp(`\\/manage\\/data-jobs$`)); - }); - - it('Data Jobs Manage Page - refresh shows newly created job', () => { - cy.fixture('lib/explore/additional-test-job.json').then((additionalTestJob) => { - const normalizedTestJob = applyGlobalEnvSettings(additionalTestJob); - - cy.log('Fixture for name: ' + normalizedTestJob.job_name); + .should("be.visible"); + + // do search + dataJobsManagePage.searchByJobName(testJobs[0].job_name); + dataJobsManagePage.waitForViewToRender(); + + // verify 1 test row visible dataJobsManagePage - .chooseQuickFilter(0); + .getDataGridCell(testJobs[0].job_name) + .scrollIntoView() + .should("be.visible"); + dataJobsManagePage + .getDataGridCell(testJobs[1].job_name) + .should("not.exist"); + // verify url contains search value dataJobsManagePage - .sortByJobName(); + .getCurrentUrl() + .should( + "match", + new RegExp( + `\\/manage\\/data-jobs\\?search=${testJobs[0].job_name}$` + ) + ); + + // clear search with clear() method + dataJobsManagePage.clearSearchField(); + dataJobsManagePage.waitForViewToRender(); + + // verify 2 test rows visible dataJobsManagePage .getDataGridCell(testJobs[0].job_name) - .should('have.text', testJobs[0].job_name); - + .scrollIntoView() + .should("be.visible"); dataJobsManagePage - .getDataGridCell(normalizedTestJob.job_name) - .should('not.exist'); + .getDataGridCell(testJobs[1].job_name) + .scrollIntoView() + .should("be.visible"); + // verify url does not contain search value dataJobsManagePage - .prepareAdditionalTestJob(); + .getCurrentUrl() + .should("match", new RegExp(`\\/manage\\/data-jobs$`)); + }); + it("Data Jobs Manage Page - grid search perform search when URL contains search parameter", () => { + // navigate with search value in URL + dataJobsManagePage = DataJobsManagePage.navigateToUrl( + `/manage/data-jobs?search=${testJobs[1].job_name}` + ); + + dataJobsManagePage.chooseQuickFilter(0); + + dataJobsManagePage.sortByJobName(); + + // verify url contains search value + dataJobsManagePage + .getCurrentUrl() + .should( + "match", + new RegExp( + `\\/manage\\/data-jobs\\?search=${testJobs[1].job_name}$` + ) + ); + + // verify 1 test row visible + dataJobsManagePage + .getDataGridCell(testJobs[0].job_name) + .should("not.exist"); dataJobsManagePage - .refreshDataGrid(); + .getDataGridCell(testJobs[1].job_name) + .scrollIntoView() + .should("be.visible"); + + // clear search with button + dataJobsManagePage.clearSearchFieldWithButton(); + // verify 2 test rows visible dataJobsManagePage - .filterByJobName(normalizedTestJob.job_name); + .getDataGridCell(testJobs[0].job_name) + .scrollIntoView() + .should("be.visible"); + dataJobsManagePage + .getDataGridCell(testJobs[1].job_name) + .scrollIntoView() + .should("be.visible"); + // verify url does not contain search value dataJobsManagePage - .getDataGridCell(normalizedTestJob.job_name) - .should('have.text', normalizedTestJob.job_name); + .getCurrentUrl() + .should("match", new RegExp(`\\/manage\\/data-jobs$`)); }); - }); - - it('Data Jobs Manage Page - click on edit button opens new page with Job details', { tags: '@integration' }, () => { - dataJobsManagePage - .clickOnContentContainer(); - - dataJobsManagePage - .chooseQuickFilter(0); - - dataJobsManagePage - .sortByJobName(); - - dataJobsManagePage - .openJobDetails(testJobs[0].team, testJobs[0].job_name); - - const dataJobManageDetailsPage = DataJobManageDetailsPage - .getPage(); - - dataJobManageDetailsPage - .getMainTitle() - .should('be.visible') - .should('contains.text', testJobs[0].job_name); - - dataJobManageDetailsPage - .getDescription() - .should('be.visible') - .should('contain.text', testJobs[0].description.split(' ').slice(0, descriptionWordsBeforeTruncate).join(' ')) - - dataJobManageDetailsPage - .getSchedule() - .should('be.visible'); - - dataJobManageDetailsPage - .getDeploymentStatus('not-deployed') - .should('be.visible') - .should('have.text', 'Not Deployed'); - }); - - it('Data Jobs Manage Page - disable/enable job', { tags: '@integration' }, () => { - dataJobsManagePage - .clickOnContentContainer(); - - dataJobsManagePage - .chooseQuickFilter(0); - - const jobName = longLivedTestJob.job_name; - const team = longLivedTestJob.team; - - dataJobsManagePage - .searchByJobName(jobName); - - //Toggle job status twice, enable to disable and vice versa. - dataJobsManagePage.toggleJobStatus(longLivedTestJob.job_name); - dataJobsManagePage.toggleJobStatus(longLivedTestJob.job_name); - }); - - it('Data Jobs Manage Page - quick filters', { tags: '@integration' }, () => { - // Disable data job before test start - DataJobsManagePage - .changeJobStatus(longLivedFailingTestJob.team, longLivedFailingTestJob.job_name, true) - .then(() => - DataJobsManagePage.changeJobStatus(longLivedTestJob.team, longLivedTestJob.job_name, false) - ) - .then(() => { - dataJobsManagePage - .clickOnContentContainer(); - dataJobsManagePage - .waitForClickThinkingTime(); - dataJobsManagePage - .chooseQuickFilter(0); - dataJobsManagePage - .waitForViewToRender(); + it("Data Jobs Manage Page - refresh shows newly created job", () => { + cy.fixture("lib/explore/additional-test-job.json").then( + (additionalTestJob) => { + const normalizedTestJob = + applyGlobalEnvSettings(additionalTestJob); - dataJobsManagePage - .getDataGridStatusIcons() - .then(($icons) => { - for (const icon of Array.from($icons)) { - cy.wrap(icon).invoke('attr', 'data-cy') - .should('match', new RegExp('data-pipelines-job-(enabled|disabled|not-deployed)')); - } - }); + cy.log("Fixture for name: " + normalizedTestJob.job_name); - dataJobsManagePage - .waitForClickThinkingTime(); - dataJobsManagePage - .chooseQuickFilter(1); - dataJobsManagePage - .waitForViewToRender(); + dataJobsManagePage.chooseQuickFilter(0); - dataJobsManagePage - .getDataGridStatusIcons() - .then(($icons) => { - for (const icon of Array.from($icons)) { - cy.wrap(icon).should('have.attr', 'data-cy', 'data-pipelines-job-enabled'); - } - }); + dataJobsManagePage.sortByJobName(); - dataJobsManagePage - .waitForClickThinkingTime(); - dataJobsManagePage - .chooseQuickFilter(2); - dataJobsManagePage - .waitForViewToRender(); + dataJobsManagePage + .getDataGridCell(testJobs[0].job_name) + .should("have.text", testJobs[0].job_name); - dataJobsManagePage - .getDataGridStatusIcons() - .then(($icons) => { - for (const icon of Array.from($icons)) { - cy.wrap(icon).should('have.attr', 'data-cy', 'data-pipelines-job-disabled'); - } - }); + dataJobsManagePage + .getDataGridCell(normalizedTestJob.job_name) + .should("not.exist"); - dataJobsManagePage - .waitForClickThinkingTime(); - dataJobsManagePage - .chooseQuickFilter(3); - dataJobsManagePage - .waitForViewToRender(); + dataJobsManagePage.prepareAdditionalTestJob(); - dataJobsManagePage - .getDataGridStatusIcons() - .then(($icons) => { - for (const icon of Array.from($icons)) { - cy.wrap(icon).should('have.attr', 'data-cy', 'data-pipelines-job-not-deployed'); - } + dataJobsManagePage.refreshDataGrid(); + + dataJobsManagePage.filterByJobName( + normalizedTestJob.job_name + ); + + dataJobsManagePage + .getDataGridCell(normalizedTestJob.job_name) + .should("have.text", normalizedTestJob.job_name); + } + ); + }); + + it( + "Data Jobs Manage Page - click on edit button opens new page with Job details", + { tags: "@integration" }, + () => { + dataJobsManagePage.clickOnContentContainer(); + + dataJobsManagePage.chooseQuickFilter(0); + + dataJobsManagePage.sortByJobName(); + + dataJobsManagePage.openJobDetails( + testJobs[0].team, + testJobs[0].job_name + ); + + const dataJobManageDetailsPage = + DataJobManageDetailsPage.getPage(); + + dataJobManageDetailsPage + .getMainTitle() + .should("be.visible") + .should("contains.text", testJobs[0].job_name); + + dataJobManageDetailsPage + .getDescription() + .should("be.visible") + .should( + "contain.text", + testJobs[0].description + .split(" ") + .slice(0, descriptionWordsBeforeTruncate) + .join(" ") + ); + + dataJobManageDetailsPage.getSchedule().should("be.visible"); + + dataJobManageDetailsPage + .getDeploymentStatus("not-deployed") + .should("be.visible") + .should("have.text", "Not Deployed"); + } + ); + + it( + "Data Jobs Manage Page - disable/enable job", + { tags: "@integration" }, + () => { + dataJobsManagePage.clickOnContentContainer(); + + dataJobsManagePage.chooseQuickFilter(0); + + const jobName = longLivedTestJob.job_name; + const team = longLivedTestJob.team; + + dataJobsManagePage.searchByJobName(jobName); + + //Toggle job status twice, enable to disable and vice versa. + dataJobsManagePage.toggleJobStatus(longLivedTestJob.job_name); + dataJobsManagePage.toggleJobStatus(longLivedTestJob.job_name); + } + ); + + it( + "Data Jobs Manage Page - quick filters", + { tags: "@integration" }, + () => { + // Disable data job before test start + DataJobsManagePage.changeJobStatus( + longLivedFailingTestJob.team, + longLivedFailingTestJob.job_name, + true + ) + .then(() => + DataJobsManagePage.changeJobStatus( + longLivedTestJob.team, + longLivedTestJob.job_name, + false + ) + ) + .then(() => { + dataJobsManagePage.clickOnContentContainer(); + + dataJobsManagePage.waitForClickThinkingTime(); + dataJobsManagePage.chooseQuickFilter(0); + dataJobsManagePage.waitForViewToRender(); + + dataJobsManagePage + .getDataGridStatusIcons() + .then(($icons) => { + for (const icon of Array.from($icons)) { + cy.wrap(icon) + .invoke("attr", "data-cy") + .should( + "match", + new RegExp( + "data-pipelines-job-(enabled|disabled|not-deployed)" + ) + ); + } + }); + + dataJobsManagePage.waitForClickThinkingTime(); + dataJobsManagePage.chooseQuickFilter(1); + dataJobsManagePage.waitForViewToRender(); + + dataJobsManagePage + .getDataGridStatusIcons() + .then(($icons) => { + for (const icon of Array.from($icons)) { + cy.wrap(icon).should( + "have.attr", + "data-cy", + "data-pipelines-job-enabled" + ); + } + }); + + dataJobsManagePage.waitForClickThinkingTime(); + dataJobsManagePage.chooseQuickFilter(2); + dataJobsManagePage.waitForViewToRender(); + + dataJobsManagePage + .getDataGridStatusIcons() + .then(($icons) => { + for (const icon of Array.from($icons)) { + cy.wrap(icon).should( + "have.attr", + "data-cy", + "data-pipelines-job-disabled" + ); + } + }); + + dataJobsManagePage.waitForClickThinkingTime(); + dataJobsManagePage.chooseQuickFilter(3); + dataJobsManagePage.waitForViewToRender(); + + dataJobsManagePage + .getDataGridStatusIcons() + .then(($icons) => { + for (const icon of Array.from($icons)) { + cy.wrap(icon).should( + "have.attr", + "data-cy", + "data-pipelines-job-not-deployed" + ); + } + }); + + // Enable data job after job end + DataJobsManagePage.changeJobStatus( + longLivedTestJob.team, + longLivedTestJob.job_name, + true + ); }); + } + ); - // Enable data job after job end - DataJobsManagePage.changeJobStatus(longLivedTestJob.team, longLivedTestJob.job_name, true); - }); - }); - - it('Data Jobs Manage Page - show/hide column when toggling from menu', () => { - // show panel for show/hide columns - dataJobsManagePage - .toggleColumnShowHidePanel(); - - // verify correct options are rendered - dataJobsManagePage - .getDataGridColumnShowHideOptionsValues() - .should('have.length', 10) - .invoke('join', ',') - .should('eq', 'Description,Deployment Status,Last Execution Duration,Success rate,Next run (UTC),Last Deployed (UTC),Last Deployed By,Notifications,Source,Logs'); - - // verify column is not checked in toggling menu - dataJobsManagePage - .getDataGridColumnShowHideOption('Notifications') - .should('exist') - .should('not.be.checked'); - - // verify header cell for column is not rendered - dataJobsManagePage - .getDataGridHeaderCell('Notifications') - .should('have.length', 0); - - // toggle column to render - dataJobsManagePage - .checkColumnShowHideOption('Notifications'); - - // verify column is checked in toggling menu - dataJobsManagePage - .getDataGridColumnShowHideOption('Notifications') - .should('exist') - .should('be.checked'); - - // verify header cell for column is rendered - dataJobsManagePage - .getDataGridHeaderCell('Notifications') - .should('have.length', 1); - - // toggle column to hide - dataJobsManagePage - .uncheckColumnShowHideOption('Notifications'); - - // verify column is not checked in toggling menu - dataJobsManagePage - .getDataGridColumnShowHideOption('Notifications') - .should('exist') - .should('not.be.checked'); - - // verify header cell for column is not rendered - dataJobsManagePage - .getDataGridHeaderCell('Notifications') - .should('have.length', 0); - - // hide panel for show/hide columns - dataJobsManagePage - .toggleColumnShowHidePanel(); - }); - - it('Data Jobs Manage Page - execute now', { tags: '@integration' }, () => { - const jobName = longLivedTestJob.job_name; - const team = longLivedTestJob.team; - - dataJobsManagePage - .chooseQuickFilter(0); - - dataJobsManagePage - .sortByJobName(); - - dataJobsManagePage - .executeDataJob(jobName); - - // TODO better handling toast message. If tests are executed immediately it will return - // error 409 conflict and it will say that the job is already executing - dataJobsManagePage - .getToastTitle(10000) // Wait up to 10 seconds for Toast to show. - .should('exist') - .contains(/Data job Queued for execution|Failed, Data job is already executing/); - }); -}); + it("Data Jobs Manage Page - show/hide column when toggling from menu", () => { + // show panel for show/hide columns + dataJobsManagePage.toggleColumnShowHidePanel(); + + // verify correct options are rendered + dataJobsManagePage + .getDataGridColumnShowHideOptionsValues() + .should("have.length", 10) + .invoke("join", ",") + .should( + "eq", + "Description,Deployment Status,Last Execution Duration,Success rate,Next run (UTC),Last Deployed (UTC),Last Deployed By,Notifications,Source,Logs" + ); + + // verify column is not checked in toggling menu + dataJobsManagePage + .getDataGridColumnShowHideOption("Notifications") + .should("exist") + .should("not.be.checked"); + + // verify header cell for column is not rendered + dataJobsManagePage + .getDataGridHeaderCell("Notifications") + .should("have.length", 0); + + // toggle column to render + dataJobsManagePage.checkColumnShowHideOption("Notifications"); + + // verify column is checked in toggling menu + dataJobsManagePage + .getDataGridColumnShowHideOption("Notifications") + .should("exist") + .should("be.checked"); + + // verify header cell for column is rendered + dataJobsManagePage + .getDataGridHeaderCell("Notifications") + .should("have.length", 1); + + // toggle column to hide + dataJobsManagePage.uncheckColumnShowHideOption("Notifications"); + + // verify column is not checked in toggling menu + dataJobsManagePage + .getDataGridColumnShowHideOption("Notifications") + .should("exist") + .should("not.be.checked"); + + // verify header cell for column is not rendered + dataJobsManagePage + .getDataGridHeaderCell("Notifications") + .should("have.length", 0); + + // hide panel for show/hide columns + dataJobsManagePage.toggleColumnShowHidePanel(); + }); + + it( + "Data Jobs Manage Page - execute now", + { tags: "@integration" }, + () => { + const jobName = longLivedTestJob.job_name; + const team = longLivedTestJob.team; + + dataJobsManagePage.chooseQuickFilter(0); + + dataJobsManagePage.sortByJobName(); + + dataJobsManagePage.executeDataJob(jobName); + + // TODO better handling toast message. If tests are executed immediately it will return + // error 409 conflict and it will say that the job is already executing + dataJobsManagePage + .getToastTitle(10000) // Wait up to 10 seconds for Toast to show. + .should("exist") + .contains( + /Data job Queued for execution|Failed, Data job is already executing/ + ); + } + ); + } +); diff --git a/projects/frontend/data-pipelines/gui/e2e/plugins/index.js b/projects/frontend/data-pipelines/gui/e2e/plugins/index.js index 1fd0b4f108..df19eea987 100644 --- a/projects/frontend/data-pipelines/gui/e2e/plugins/index.js +++ b/projects/frontend/data-pipelines/gui/e2e/plugins/index.js @@ -17,8 +17,11 @@ // This function is called when a project is opened or re-opened (e.g. due to // the project's config changing) -const { install, ensureBrowserFlags } = require('@neuralegion/cypress-har-generator'); -const path = require('path'); +const { + install, + ensureBrowserFlags, +} = require("@neuralegion/cypress-har-generator"); +const path = require("path"); /** * @type {Cypress.PluginConfig} @@ -28,20 +31,23 @@ module.exports = (on, config) => { outputRoot: config.env.CYPRESS_TERMINAL_LOGS, // Used to trim the base path of specs and reduce nesting in the // generated output directory. - specRoot: path.relative(config.fileServerFolder, config.integrationFolder), + specRoot: path.relative( + config.fileServerFolder, + config.integrationFolder + ), outputTarget: { - 'cypress-logs|json': 'json', + "cypress-logs|json": "json", }, - printLogsToConsole: 'always', - printLogsToFile: 'always', + printLogsToConsole: "always", + printLogsToFile: "always", includeSuccessfulHookLogs: true, - logToFilesOnAfterRun: true + logToFilesOnAfterRun: true, }; - require('cypress-terminal-report/src/installLogsPrinter')(on, options); + require("cypress-terminal-report/src/installLogsPrinter")(on, options); install(on, config); - on('before:browser:launch', (browser = {}, launchOptions) => { + on("before:browser:launch", (browser = {}, launchOptions) => { ensureBrowserFlags(browser, launchOptions); return launchOptions; }); diff --git a/projects/frontend/data-pipelines/gui/e2e/support/application/data-job-base.po.js b/projects/frontend/data-pipelines/gui/e2e/support/application/data-job-base.po.js index 54a0782984..d5f2722563 100644 --- a/projects/frontend/data-pipelines/gui/e2e/support/application/data-job-base.po.js +++ b/projects/frontend/data-pipelines/gui/e2e/support/application/data-job-base.po.js @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { DataPipelinesBasePO } from './data-pipelines-base.po'; +import { DataPipelinesBasePO } from "./data-pipelines-base.po"; export class DataJobBasePO extends DataPipelinesBasePO { static getPage() { @@ -35,35 +35,38 @@ export class DataJobBasePO extends DataPipelinesBasePO { } waitForDataJobStartExecute() { - cy.waitForInterceptor('@getExecutionsRequest', 20, (response) => { + cy.waitForInterceptor("@getExecutionsRequest", 20, (response) => { return response?.data?.content?.findIndex((e) => { - return e.status?.toLowerCase() === 'running' || e.status?.toLowerCase() === 'submitted' + return ( + e.status?.toLowerCase() === "running" || + e.status?.toLowerCase() === "submitted" + ); }); }); } waitForDataJobStopExecute() { - cy.waitForInterceptor('@getExecutionRequest', 20, (response) => { - return response?.status === 'cancelled'; + cy.waitForInterceptor("@getExecutionRequest", 20, (response) => { + return response?.status === "cancelled"; }); } /* Selectors */ getNavigateBackBtn() { - return cy.get('[data-cy=data-pipelines-job-navigate-back]'); + return cy.get("[data-cy=data-pipelines-job-navigate-back]"); } getMainTitle() { - return cy.get('[data-cy=data-pipelines-job-main-title]'); + return cy.get("[data-cy=data-pipelines-job-main-title]"); } getExecuteNowButton() { - return cy.get('[data-cy=data-pipelines-job-execute-btn]'); + return cy.get("[data-cy=data-pipelines-job-execute-btn]"); } getCancelExecutionButton() { - return cy.get('[data-cy=data-pipelines-job-cancel-execution-btn]'); + return cy.get("[data-cy=data-pipelines-job-cancel-execution-btn]"); } getConfirmDialogButton() { @@ -71,27 +74,27 @@ export class DataJobBasePO extends DataPipelinesBasePO { } getActionDropdownBtn() { - return cy.get('[data-cy=data-pipelines-job-action-dropdown-btn]'); + return cy.get("[data-cy=data-pipelines-job-action-dropdown-btn]"); } getDownloadKeyBtn() { - return cy.get('[data-cy=data-pipelines-job-download-btn]'); + return cy.get("[data-cy=data-pipelines-job-download-btn]"); } getDeleteJobBtn() { - return cy.get('[data-cy=data-pipelines-job-delete-btn]'); + return cy.get("[data-cy=data-pipelines-job-delete-btn]"); } getConfirmDeleteBtn() { - return cy.get('#removeBtn'); + return cy.get("#removeBtn"); } getDetailsTab() { - return cy.get('[data-cy=data-pipelines-job-details-tab]'); + return cy.get("[data-cy=data-pipelines-job-details-tab]"); } getExecutionsTab() { - return cy.get('[data-cy=data-pipelines-job-executions-tab]'); + return cy.get("[data-cy=data-pipelines-job-executions-tab]"); } getExecutionStatus() { @@ -101,15 +104,13 @@ export class DataJobBasePO extends DataPipelinesBasePO { /* Actions */ executeNow() { - this.getExecuteNowButton() - .scrollIntoView() - .click({ force: true }); + this.getExecuteNowButton().scrollIntoView().click({ force: true }); } openActionDropdown() { this.getActionDropdownBtn() .scrollIntoView() - .should('be.visible') + .should("be.visible") .click({ force: true }); this.waitForClickThinkingTime(); @@ -118,7 +119,7 @@ export class DataJobBasePO extends DataPipelinesBasePO { downloadJobKey() { this.getDownloadKeyBtn() .scrollIntoView() - .should('be.visible') + .should("be.visible") .click({ force: true }); this.waitForBackendRequestCompletion(); @@ -127,37 +128,31 @@ export class DataJobBasePO extends DataPipelinesBasePO { deleteJob() { this.getDeleteJobBtn() .scrollIntoView() - .should('be.visible') + .should("be.visible") .click({ force: true }); } confirmDeleteJob() { this.getConfirmDeleteBtn() .scrollIntoView() - .should('be.visible') + .should("be.visible") .click({ force: true }); } navigateBackToDataJobs() { - this.getNavigateBackBtn() - .should('be.visible') - .click({ force: true }); + this.getNavigateBackBtn().should("be.visible").click({ force: true }); this.waitForBackendRequestCompletion(); } openDetailsTab() { - this.getDetailsTab() - .should('exist') - .click({ force: true }); + this.getDetailsTab().should("exist").click({ force: true }); this.waitForBackendRequestCompletion(); } openExecutionsTab() { - this.getExecutionsTab() - .should('exist') - .click({ force: true }); + this.getExecutionsTab().should("exist").click({ force: true }); this.waitForBackendRequestCompletion(); } diff --git a/projects/frontend/data-pipelines/gui/e2e/support/application/data-job-details-base.po.js b/projects/frontend/data-pipelines/gui/e2e/support/application/data-job-details-base.po.js index 609099be4a..c33ab9895f 100644 --- a/projects/frontend/data-pipelines/gui/e2e/support/application/data-job-details-base.po.js +++ b/projects/frontend/data-pipelines/gui/e2e/support/application/data-job-details-base.po.js @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { DataJobBasePO } from './data-job-base.po'; +import { DataJobBasePO } from "./data-job-base.po"; export class DataJobDetailsBasePO extends DataJobBasePO { static getPage() { @@ -11,61 +11,61 @@ export class DataJobDetailsBasePO extends DataJobBasePO { } static navigateTo(context, teamName, jobName) { - return this.navigateToUrl(`/${ context }/data-jobs/${ teamName }/${ jobName }`); + return this.navigateToUrl( + `/${context}/data-jobs/${teamName}/${jobName}` + ); } // Selectors getStatusField() { - return cy.get('[data-cy=data-pipelines-job-details-status]'); + return cy.get("[data-cy=data-pipelines-job-details-status]"); } getDescriptionField() { - return cy.get('[data-cy=data-pipelines-job-details-description]'); + return cy.get("[data-cy=data-pipelines-job-details-description]"); } getDescriptionFull() { - return cy.get('[data-cy=description-show-less]'); + return cy.get("[data-cy=description-show-less]"); } getShowDescriptionMoreBtn() { - return cy.get('[data-cy=description-show-more]'); + return cy.get("[data-cy=description-show-more]"); } getTeamField() { - return cy.get('[data-cy=data-pipelines-job-details-team]'); + return cy.get("[data-cy=data-pipelines-job-details-team]"); } getScheduleField() { - return cy.get('[data-cy=data-pipelines-job-details-schedule]'); + return cy.get("[data-cy=data-pipelines-job-details-schedule]"); } getSourceField() { - return cy.get('[data-cy=data-pipelines-job-details-source]'); + return cy.get("[data-cy=data-pipelines-job-details-source]"); } getOnDeployedField() { - return cy.get('[data-cy=data-pipelines-job-details-on-deployed]'); + return cy.get("[data-cy=data-pipelines-job-details-on-deployed]"); } getOnPlatformErrorField() { - return cy.get('[data-cy=data-pipelines-job-details-on-platform-error]'); + return cy.get("[data-cy=data-pipelines-job-details-on-platform-error]"); } getOnUserErrorField() { - return cy.get('[data-cy=data-pipelines-job-details-on-user-error]'); + return cy.get("[data-cy=data-pipelines-job-details-on-user-error]"); } getOnSuccessField() { - return cy.get('[data-cy=data-pipelines-job-details-on-success]'); + return cy.get("[data-cy=data-pipelines-job-details-on-success]"); } // Actions showMoreDescription() { - this.getShowDescriptionMoreBtn() - .should('exist') - .click({ force: true }); + this.getShowDescriptionMoreBtn().should("exist").click({ force: true }); this.waitForViewToRenderShort(); diff --git a/projects/frontend/data-pipelines/gui/e2e/support/application/data-jobs-base.po.js b/projects/frontend/data-pipelines/gui/e2e/support/application/data-jobs-base.po.js index d4b5dd9a4a..1676bc2c0d 100644 --- a/projects/frontend/data-pipelines/gui/e2e/support/application/data-jobs-base.po.js +++ b/projects/frontend/data-pipelines/gui/e2e/support/application/data-jobs-base.po.js @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { DataPipelinesBasePO } from './data-pipelines-base.po'; +import { DataPipelinesBasePO } from "./data-pipelines-base.po"; export class DataJobsBasePO extends DataPipelinesBasePO { static getPage() { @@ -11,12 +11,11 @@ export class DataJobsBasePO extends DataPipelinesBasePO { } static navigateTo(linkSelector) { - cy.visit('/') + cy.visit("/"); cy.wait(DataJobsBasePO.INITIAL_PAGE_LOAD_WAIT_TIME); - cy.get(linkSelector) - .click({ force: true }); + cy.get(linkSelector).click({ force: true }); this.waitForBackendRequestCompletion(); @@ -28,105 +27,104 @@ export class DataJobsBasePO extends DataPipelinesBasePO { /* Selectors */ getDataGrid() { - return cy.get('clr-datagrid'); + return cy.get("clr-datagrid"); } getQuickFilters() { - return cy.get('[data-cy=data-pipelines-quick-filters] > span'); + return cy.get("[data-cy=data-pipelines-quick-filters] > span"); } getHeaderColumnJobName() { - return cy.get('[data-cy=data-pipelines-jobs-name-column]'); + return cy.get("[data-cy=data-pipelines-jobs-name-column]"); } getHeaderColumnJobNameSortBtn() { return this.getHeaderColumnJobName() - .should('exist') - .find('.datagrid-column-title'); + .should("exist") + .find(".datagrid-column-title"); } getDataGridHeaderCell(content) { return this.getDataGrid() - .should('exist') - .find('clr-dg-column:not(.datagrid-hidden-column)') - .contains(new RegExp(`${ content }`)); + .should("exist") + .find("clr-dg-column:not(.datagrid-hidden-column)") + .contains(new RegExp(`${content}`)); } // Rows and Cells getDataGridRows() { return this.getDataGrid() - .should('exist') - .find('clr-dg-row.datagrid-row'); + .should("exist") + .find("clr-dg-row.datagrid-row"); } getDataGridRow(rowIndex) { return this.getDataGridRows() - .should('have.length.gte', rowIndex - 1) - .then((rows) => Array.from(rows)[rowIndex - 1]); + .should("have.length.gte", rowIndex - 1) + .then((rows) => Array.from(rows)[rowIndex - 1]); } getDataGridCells(rowIndex) { return this.getDataGridRow(rowIndex) - .should('exist') - .find('clr-dg-cell.datagrid-cell'); + .should("exist") + .find("clr-dg-cell.datagrid-cell"); } getDataGridCellByIndex(rowIndex, cellIndex) { return this.getDataGridCells(rowIndex) - .should('have.length.gte', cellIndex - 1) - .then((cells) => Array.from(cells)[cellIndex - 1]); + .should("have.length.gte", cellIndex - 1) + .then((cells) => Array.from(cells)[cellIndex - 1]); } getDataGridCellByIdentifier(rowIndex, identifier) { - return this.getDataGridRow(rowIndex) - .should('exist') - .find(identifier) + return this.getDataGridRow(rowIndex).should("exist").find(identifier); } getDataGridStatusCells() { return this.getDataGrid() - .should('exist') - .find('[data-cy=data-pipelines-manage-grid-status-cell]'); + .should("exist") + .find("[data-cy=data-pipelines-manage-grid-status-cell]"); } getDataGridStatusIcons() { return this.getDataGrid() - .should('exist') - .find('[data-cy=data-pipelines-manage-grid-status-cell] clr-icon[data-cy*=data-pipelines-job]'); + .should("exist") + .find( + "[data-cy=data-pipelines-manage-grid-status-cell] clr-icon[data-cy*=data-pipelines-job]" + ); } getDataGridColumnToggle() { return this.getDataGrid() - .should('exist') - .find('clr-dg-column-toggle button'); + .should("exist") + .find("clr-dg-column-toggle button"); } getDataGridColumnShowHidePanel() { - return cy.get('.column-switch'); + return cy.get(".column-switch"); } getDataGridColumnShowHideOptions() { return this.getDataGridColumnShowHidePanel() - .should('exist') - .find('clr-checkbox-wrapper'); + .should("exist") + .find("clr-checkbox-wrapper"); } getDataGridColumnShowHideOptionsValues() { return this.getDataGridColumnShowHidePanel() - .should('exist') - .find('clr-checkbox-wrapper') - .then((elements) => Array.from(elements).map((el) => el.innerText)); + .should("exist") + .find("clr-checkbox-wrapper") + .then((elements) => Array.from(elements).map((el) => el.innerText)); } getDataGridColumnShowHideOption(option) { return this.getDataGridColumnShowHideOptions() - .should('have.length.gt', 0) - .then((elements) => - Array.from(elements) - .find((el) => el.innerText === option) - ) - .find('input'); + .should("have.length.gt", 0) + .then((elements) => + Array.from(elements).find((el) => el.innerText === option) + ) + .find("input"); } /* Actions */ @@ -136,7 +134,7 @@ export class DataJobsBasePO extends DataPipelinesBasePO { .then((filters) => { return filters && filters[filterPosition]; }) - .should('exist') + .should("exist") .click({ force: true }); this.waitForBackendRequestCompletion(); @@ -146,7 +144,7 @@ export class DataJobsBasePO extends DataPipelinesBasePO { sortByJobName() { this.getHeaderColumnJobNameSortBtn() - .should('exist') + .should("exist") .click({ force: true }); this.waitForBackendRequestCompletion(); @@ -155,16 +153,14 @@ export class DataJobsBasePO extends DataPipelinesBasePO { } toggleColumnShowHidePanel() { - this.getDataGridColumnToggle() - .should('exist') - .click({ force: true }); + this.getDataGridColumnToggle().should("exist").click({ force: true }); this.waitForClickThinkingTime(); } checkColumnShowHideOption(option) { this.getDataGridColumnShowHideOption(option) - .should('exist') + .should("exist") .check({ force: true }); this.waitForViewToRenderShort(); @@ -172,7 +168,7 @@ export class DataJobsBasePO extends DataPipelinesBasePO { uncheckColumnShowHideOption(option) { this.getDataGridColumnShowHideOption(option) - .should('exist') + .should("exist") .uncheck({ force: true }); this.waitForViewToRenderShort(); diff --git a/projects/frontend/data-pipelines/gui/e2e/support/application/data-pipelines-base.po.js b/projects/frontend/data-pipelines/gui/e2e/support/application/data-pipelines-base.po.js index 3cd77e6c1c..00463584a8 100644 --- a/projects/frontend/data-pipelines/gui/e2e/support/application/data-pipelines-base.po.js +++ b/projects/frontend/data-pipelines/gui/e2e/support/application/data-pipelines-base.po.js @@ -80,7 +80,6 @@ export class DataPipelinesBasePO { return cy.changeDataJobEnabledStatus(teamName, jobName, status); } - // Interceptors and waiting waitForBackendRequestCompletion(numberOfReqToWait = 1) { @@ -122,7 +121,7 @@ export class DataPipelinesBasePO { /* Selectors */ getMainTitle() { - return cy.get('[data-cy=dp-main-title]'); + return cy.get("[data-cy=dp-main-title]"); } getCurrentUrl() { @@ -130,31 +129,29 @@ export class DataPipelinesBasePO { } getToast(timeout) { - return cy.get('vdk-toast-container vdk-toast', { timeout: this.resolveTimeout(timeout) }); + return cy.get("vdk-toast-container vdk-toast", { + timeout: this.resolveTimeout(timeout), + }); } getToastTitle(timeout) { - return this - .getToast(timeout) - .get('.toast-title'); + return this.getToast(timeout).get(".toast-title"); } getToastDismiss(timeout) { - return this - .getToast(timeout) - .get('.dismiss-bg'); + return this.getToast(timeout).get(".dismiss-bg"); } getContentContainer() { - return cy.get('div.content-container'); + return cy.get("div.content-container"); } /* Actions */ confirmInConfirmDialog() { - cy.get('[data-cy=confirmation-dialog-ok-btn]') - .should('exist') - .click({ force: true }); + cy.get("[data-cy=confirmation-dialog-ok-btn]") + .should("exist") + .click({ force: true }); this.waitForBackendRequestCompletion(); @@ -162,21 +159,19 @@ export class DataPipelinesBasePO { } clickOnContentContainer() { - this.getContentContainer() - .should('exist') - .click({ force: true }); + this.getContentContainer().should("exist").click({ force: true }); this.waitForSmartDelay(); } resolveTimeout(timeout) { return timeout === undefined - ? Cypress.config('defaultCommandTimeout') + ? Cypress.config("defaultCommandTimeout") : timeout; } readFile(folderName, fileName) { - const path = require('path'); + const path = require("path"); const downloadsFolder = Cypress.config(folderName); return cy.readFile(path.join(downloadsFolder, fileName)); diff --git a/projects/frontend/data-pipelines/gui/e2e/support/commands.js b/projects/frontend/data-pipelines/gui/e2e/support/commands.js index e1e3ebd8d9..47d685a4e3 100644 --- a/projects/frontend/data-pipelines/gui/e2e/support/commands.js +++ b/projects/frontend/data-pipelines/gui/e2e/support/commands.js @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import 'cypress-localstorage-commands'; +import "cypress-localstorage-commands"; import { applyGlobalEnvSettings, @@ -11,242 +11,311 @@ import { createTestJob, deleteTestJobIfExists, deployTestJobIfNotExists, - waitForJobExecutionCompletion -} from './helpers/commands.helpers'; - -Cypress.Commands.add('login', () => { - return cy.request({ - method: 'POST', - // See project README.md how to set this login url - url: Cypress.env('login_url'), - form: true, - body: { - // See project README.md how to set this token - api_token: Cypress.env('OAUTH2_API_TOKEN') - }, - followRedirect: false, - failOnStatusCode: false - }) - .its('body') - .then((body) => { - const token = body.access_token; - const expiresIn = body.expires_in; - const idToken = body.id_token; - const expiresAt = JSON.stringify(Date.now() + (expiresIn * 1000)); - - window.localStorage.setItem('expires_at', expiresAt); - window.localStorage.setItem('access_token', token); - window.localStorage.setItem('id_token', idToken); - - // Set the CSP token in the session storage to enable the Integration testing against Management UI - sessionStorage.setItem('expires_at', expiresAt); - sessionStorage.setItem('access_token', token); - sessionStorage.setItem('id_token', idToken); - - return cy.wrap({ context: 'commands::login()', action: 'continue' }); - }); -}); - -Cypress.Commands.add('initBackendRequestInterceptor', () => { + waitForJobExecutionCompletion, +} from "./helpers/commands.helpers"; + +Cypress.Commands.add("login", () => { + return cy + .request({ + method: "POST", + // See project README.md how to set this login url + url: Cypress.env("login_url"), + form: true, + body: { + // See project README.md how to set this token + api_token: Cypress.env("OAUTH2_API_TOKEN"), + }, + followRedirect: false, + failOnStatusCode: false, + }) + .its("body") + .then((body) => { + const token = body.access_token; + const expiresIn = body.expires_in; + const idToken = body.id_token; + const expiresAt = JSON.stringify(Date.now() + expiresIn * 1000); + + window.localStorage.setItem("expires_at", expiresAt); + window.localStorage.setItem("access_token", token); + window.localStorage.setItem("id_token", idToken); + + // Set the CSP token in the session storage to enable the Integration testing against Management UI + sessionStorage.setItem("expires_at", expiresAt); + sessionStorage.setItem("access_token", token); + sessionStorage.setItem("id_token", idToken); + + return cy.wrap({ + context: "commands::login()", + action: "continue", + }); + }); +}); + +Cypress.Commands.add("initBackendRequestInterceptor", () => { cy.intercept({ - method:'GET', - url:'**/data-jobs/for-team/**'}) - .as('getJobsRequest'); + method: "GET", + url: "**/data-jobs/for-team/**", + }).as("getJobsRequest"); }); -Cypress.Commands.add('waitForBackendRequestCompletion', () => { - cy.wait('@getJobsRequest'); +Cypress.Commands.add("waitForBackendRequestCompletion", () => { + cy.wait("@getJobsRequest"); }); -Cypress.Commands.add('initGetExecutionsInterceptor', () => { - cy.intercept('GET', '**/data-jobs/for-team/**', (req) => { - if (req?.query?.operationName === 'jobsQuery' && req?.query?.query?.includes('executions')) { - req.alias = 'getExecutionsRequest'; +Cypress.Commands.add("initGetExecutionsInterceptor", () => { + cy.intercept("GET", "**/data-jobs/for-team/**", (req) => { + if ( + req?.query?.operationName === "jobsQuery" && + req?.query?.query?.includes("executions") + ) { + req.alias = "getExecutionsRequest"; } - }) + }); }); -Cypress.Commands.add('initGetExecutionInterceptor', () => { +Cypress.Commands.add("initGetExecutionInterceptor", () => { cy.intercept({ - method: 'GET', - url: '**/data-jobs/for-team/**/executions/**' - }) - .as('getExecutionRequest'); + method: "GET", + url: "**/data-jobs/for-team/**/executions/**", + }).as("getExecutionRequest"); }); -Cypress.Commands.add('waitForInterceptor', (aliasName, retries, predicate) => { - cy.wait(aliasName).its('response.body').then((json) => { - - if (predicate(json)) { - return; - } - - if (retries > 0) { - cy.waitForInterceptor(aliasName, retries - 1, predicate); - } - }); +Cypress.Commands.add("waitForInterceptor", (aliasName, retries, predicate) => { + cy.wait(aliasName) + .its("response.body") + .then((json) => { + if (predicate(json)) { + return; + } + + if (retries > 0) { + cy.waitForInterceptor(aliasName, retries - 1, predicate); + } + }); }); -Cypress.Commands.add('initPostExecutionInterceptor', () => { +Cypress.Commands.add("initPostExecutionInterceptor", () => { cy.intercept({ - method: 'POST', - url: '**/data-jobs/for-team/**/executions' - }).as('postExecuteNow'); + method: "POST", + url: "**/data-jobs/for-team/**/executions", + }).as("postExecuteNow"); }); -Cypress.Commands.add('waitForPostExecutionCompletion', () => { - cy.wait('@postExecuteNow'); +Cypress.Commands.add("waitForPostExecutionCompletion", () => { + cy.wait("@postExecuteNow"); }); -Cypress.Commands.add('initDeleteExecutionInterceptor', () => { +Cypress.Commands.add("initDeleteExecutionInterceptor", () => { cy.intercept({ - method: 'DELETE', - url: '**/data-jobs/for-team/**/executions/**' - }).as('deleteExecution'); + method: "DELETE", + url: "**/data-jobs/for-team/**/executions/**", + }).as("deleteExecution"); }); -Cypress.Commands.add('waitForDeleteExecutionCompletion', () => { - cy.wait('@deleteExecution'); +Cypress.Commands.add("waitForDeleteExecutionCompletion", () => { + cy.wait("@deleteExecution"); }); -Cypress.Commands.add('recordHarIfSupported', () => { - if (Cypress.browser.name === 'chrome') { - return cy.recordHar({ excludePaths: ['vendor.js$', 'clr-ui.min.css$', 'scripts.js$', 'polyfills.js$'] }); +Cypress.Commands.add("recordHarIfSupported", () => { + if (Cypress.browser.name === "chrome") { + return cy.recordHar({ + excludePaths: [ + "vendor.js$", + "clr-ui.min.css$", + "scripts.js$", + "polyfills.js$", + ], + }); } - return cy.wrap({ context: 'commands::recordHarIfSupported()', action: 'continue' }); + return cy.wrap({ + context: "commands::recordHarIfSupported()", + action: "continue", + }); }); -Cypress.Commands.add('saveHarIfSupported', () => { - if (Cypress.browser.name === 'chrome') { +Cypress.Commands.add("saveHarIfSupported", () => { + if (Cypress.browser.name === "chrome") { return cy.saveHar(); } - return cy.wrap({ context: 'commands::saveHarIfSupported()', action: 'continue' }); + return cy.wrap({ + context: "commands::saveHarIfSupported()", + action: "continue", + }); }); -Cypress.Commands.add('prepareBaseTestJobs', () => { - return cy.fixture('lib/explore/test-jobs.json') - .then((testJobs) => { - return Promise.all( - testJobs.map((testJob) => { - const normalizedTestJob = applyGlobalEnvSettings(testJob); +Cypress.Commands.add("prepareBaseTestJobs", () => { + return cy.fixture("lib/explore/test-jobs.json").then((testJobs) => { + return Promise.all( + testJobs.map((testJob) => { + const normalizedTestJob = applyGlobalEnvSettings(testJob); - return createTestJob(normalizedTestJob); - }) - ); - }); + return createTestJob(normalizedTestJob); + }) + ); + }); }); -Cypress.Commands.add('prepareAdditionalTestJobs', () => { - return cy.fixture('lib/explore/additional-test-job.json') - .then((testJob) => { - const normalizedTestJob = applyGlobalEnvSettings(testJob); +Cypress.Commands.add("prepareAdditionalTestJobs", () => { + return cy + .fixture("lib/explore/additional-test-job.json") + .then((testJob) => { + const normalizedTestJob = applyGlobalEnvSettings(testJob); - return createTestJob(normalizedTestJob); - }) + return createTestJob(normalizedTestJob); + }); }); -Cypress.Commands.add('prepareLongLivedTestJob', () => { - return deployTestJobIfNotExists('lib/manage/e2e-cypress-dp-test.json', 'lib/manage/e2e-cypress-dp-test.zip'); +Cypress.Commands.add("prepareLongLivedTestJob", () => { + return deployTestJobIfNotExists( + "lib/manage/e2e-cypress-dp-test.json", + "lib/manage/e2e-cypress-dp-test.zip" + ); }); -Cypress.Commands.add('prepareLongLivedFailingTestJob', () => { - return deployTestJobIfNotExists('e2e-cy-dp-failing.job.json', 'e2e-cy-dp-failing.job.zip'); +Cypress.Commands.add("prepareLongLivedFailingTestJob", () => { + return deployTestJobIfNotExists( + "e2e-cy-dp-failing.job.json", + "e2e-cy-dp-failing.job.zip" + ); }); -Cypress.Commands.add('cleanTestJobs', () => { - return cy.fixture('lib/explore/test-jobs.json') - .then((testJobs) => { - return Promise.all( - testJobs.map((testJob) => { - const normalizedTestJob = applyGlobalEnvSettings(testJob); - - return deleteTestJobIfExists(normalizedTestJob); - }) - ); - }) - .then(() => { - return cy.fixture('lib/explore/additional-test-job.json') - .then((testJob) => { - const normalizedTestJob = applyGlobalEnvSettings(testJob); - - return deleteTestJobIfExists(normalizedTestJob); - }); - }); +Cypress.Commands.add("cleanTestJobs", () => { + return cy + .fixture("lib/explore/test-jobs.json") + .then((testJobs) => { + return Promise.all( + testJobs.map((testJob) => { + const normalizedTestJob = applyGlobalEnvSettings(testJob); + + return deleteTestJobIfExists(normalizedTestJob); + }) + ); + }) + .then(() => { + return cy + .fixture("lib/explore/additional-test-job.json") + .then((testJob) => { + const normalizedTestJob = applyGlobalEnvSettings(testJob); + + return deleteTestJobIfExists(normalizedTestJob); + }); + }); }); -Cypress.Commands.add('waitForTestJobExecutionCompletion', () => { +Cypress.Commands.add("waitForTestJobExecutionCompletion", () => { const waitForJobExecutionTimeout = 180000; // Wait up to 3 min for job execution to complete - return cy.fixture('lib/manage/e2e-cypress-dp-test.json') - .then((testJob) => { - const normalizedTestJob = applyGlobalEnvSettings(testJob); + return cy.fixture("lib/manage/e2e-cypress-dp-test.json").then((testJob) => { + const normalizedTestJob = applyGlobalEnvSettings(testJob); - return waitForJobExecutionCompletion(normalizedTestJob.team, normalizedTestJob.job_name, waitForJobExecutionTimeout); - }); + return waitForJobExecutionCompletion( + normalizedTestJob.team, + normalizedTestJob.job_name, + waitForJobExecutionTimeout + ); + }); }); -Cypress.Commands.add('createTwoExecutionsLongLivedTestJob', () => { +Cypress.Commands.add("createTwoExecutionsLongLivedTestJob", () => { const waitForJobExecutionTimeout = 180000; // Wait up to 3 min for job execution to complete - return cy.fixture('lib/manage/e2e-cypress-dp-test.json') - .then((testJob) => { - const normalizedTestJob = applyGlobalEnvSettings(testJob); + return cy.fixture("lib/manage/e2e-cypress-dp-test.json").then((testJob) => { + const normalizedTestJob = applyGlobalEnvSettings(testJob); - return createExecutionsForJob(normalizedTestJob.team, normalizedTestJob.job_name, waitForJobExecutionTimeout, 2); - }); + return createExecutionsForJob( + normalizedTestJob.team, + normalizedTestJob.job_name, + waitForJobExecutionTimeout, + 2 + ); + }); }); -Cypress.Commands.add('createExecutionsLongLivedFailingTestJob', () => { +Cypress.Commands.add("createExecutionsLongLivedFailingTestJob", () => { const waitForJobExecutionTimeout = 180000; // Wait up to 3 min for job execution to complete - return cy.fixture('e2e-cy-dp-failing.job.json') - .then((failingTestJob) => { - const normalizedTestJob = applyGlobalEnvSettings(failingTestJob); - - return createExecutionsForJob(normalizedTestJob.team, normalizedTestJob.job_name, waitForJobExecutionTimeout, 2); - }); -}); - -Cypress.Commands.add('changeDataJobEnabledStatus', (teamName, jobName, status) => { - return cy.request({ - url: Cypress.env('data_jobs_url') + `/data-jobs/for-team/${ teamName }/jobs/${ jobName }/deployments`, - method: 'get', - auth: { - 'bearer': window.localStorage.getItem('access_token') - }, - failOnStatusCode: false - }).then((outerResponse) => { - if (outerResponse.status === 200) { - const lastDeployment = outerResponse.body[outerResponse.body.length - 1]; - const lastDeploymentHash = lastDeployment.job_version; - - return cy.request({ - url: Cypress.env('data_jobs_url') + `/data-jobs/for-team/${ teamName }/jobs/${ jobName }/deployments/${ lastDeploymentHash }`, - method: 'patch', - body: { enabled: status }, + return cy.fixture("e2e-cy-dp-failing.job.json").then((failingTestJob) => { + const normalizedTestJob = applyGlobalEnvSettings(failingTestJob); + + return createExecutionsForJob( + normalizedTestJob.team, + normalizedTestJob.job_name, + waitForJobExecutionTimeout, + 2 + ); + }); +}); + +Cypress.Commands.add( + "changeDataJobEnabledStatus", + (teamName, jobName, status) => { + return cy + .request({ + url: + Cypress.env("data_jobs_url") + + `/data-jobs/for-team/${teamName}/jobs/${jobName}/deployments`, + method: "get", auth: { - 'bearer': window.localStorage.getItem('access_token') + bearer: window.localStorage.getItem("access_token"), }, - failOnStatusCode: false - }).then((innerResponse) => { - if (innerResponse.status >= 200 && innerResponse.status < 300) { - cy.log(`Change enable status to [${ status }] for data job [${ jobName }]`); + failOnStatusCode: false, + }) + .then((outerResponse) => { + if (outerResponse.status === 200) { + const lastDeployment = + outerResponse.body[outerResponse.body.length - 1]; + const lastDeploymentHash = lastDeployment.job_version; + + return cy + .request({ + url: + Cypress.env("data_jobs_url") + + `/data-jobs/for-team/${teamName}/jobs/${jobName}/deployments/${lastDeploymentHash}`, + method: "patch", + body: { enabled: status }, + auth: { + bearer: window.localStorage.getItem( + "access_token" + ), + }, + failOnStatusCode: false, + }) + .then((innerResponse) => { + if ( + innerResponse.status >= 200 && + innerResponse.status < 300 + ) { + cy.log( + `Change enable status to [${status}] for data job [${jobName}]` + ); + } else { + cy.log( + `Cannot change enabled status to [${status}] for data job [${jobName}]` + ); + + console.log(`Http request:`, innerResponse); + } + + return cy.wrap({ + context: + "commands::1::changeDataJobEnabledStatus()", + action: "continue", + }); + }); } else { - cy.log(`Cannot change enabled status to [${ status }] for data job [${ jobName }]`); + cy.log( + `Cannot change enabled status to [${status}] for data job [${jobName}]` + ); - console.log(`Http request:`, innerResponse); - } + console.log(`Http request:`, outerResponse); - return cy.wrap({ context: 'commands::1::changeDataJobEnabledStatus()', action: 'continue' }); + return cy.wrap({ + context: "commands::2::changeDataJobEnabledStatus()", + action: "continue", + }); + } }); - } else { - cy.log(`Cannot change enabled status to [${ status }] for data job [${ jobName }]`); - - console.log(`Http request:`, outerResponse); - - return cy.wrap({ context: 'commands::2::changeDataJobEnabledStatus()', action: 'continue' }); - } - }); -}); + } +); diff --git a/projects/frontend/data-pipelines/gui/e2e/support/helpers/commands.helpers.js b/projects/frontend/data-pipelines/gui/e2e/support/helpers/commands.helpers.js index 7c5a904835..62096475a5 100644 --- a/projects/frontend/data-pipelines/gui/e2e/support/helpers/commands.helpers.js +++ b/projects/frontend/data-pipelines/gui/e2e/support/helpers/commands.helpers.js @@ -3,258 +3,412 @@ * SPDX-License-Identifier: Apache-2.0 */ -const DEFAULT_TEST_ENV_VAR = 'lib'; +const DEFAULT_TEST_ENV_VAR = "lib"; const applyGlobalEnvSettings = (loadedElement, injectedTestEnvVar = null) => { const TEST_ENV_VAR = injectedTestEnvVar ?? _loadTestEnvironmentVar(); - if (typeof loadedElement === 'string') { - return loadedElement.replace('$env-placeholder$', TEST_ENV_VAR); + if (typeof loadedElement === "string") { + return loadedElement.replace("$env-placeholder$", TEST_ENV_VAR); } - if (typeof loadedElement === 'object') { - Object.entries(loadedElement) - .forEach(([key, value]) => { - if (typeof value === 'string') { - if (value.includes('$env-placeholder$')) { - value = value.replace('$env-placeholder$', TEST_ENV_VAR); - } - - loadedElement[key] = value; - } - - if (typeof value === 'object') { - loadedElement[key] = applyGlobalEnvSettings(value); - } - }); + if (typeof loadedElement === "object") { + Object.entries(loadedElement).forEach(([key, value]) => { + if (typeof value === "string") { + if (value.includes("$env-placeholder$")) { + value = value.replace("$env-placeholder$", TEST_ENV_VAR); + } + + loadedElement[key] = value; + } + + if (typeof value === "object") { + loadedElement[key] = applyGlobalEnvSettings(value); + } + }); } return loadedElement; }; -const createExecutionsForJob = (teamName, jobName, waitForJobExecutionTimeout, numberOfExecutions = 2) => { - cy.log(`Trying to provide at least ${ numberOfExecutions } executions for Job "${ jobName }"`); - - return _getJobExecutions(teamName, jobName) - .then((executions) => { - cy.log(`Found ${ executions.length } executions for Job "${ jobName }" and target is ${ numberOfExecutions } executions`); - - if (executions.length >= numberOfExecutions) { - cy.log(`Skipping manual execution, expected number of executions found`); - - return cy.wrap({ context: 'commands.helpers::1::createExecutionsForJob()', action: 'continue' }); - } +const createExecutionsForJob = ( + teamName, + jobName, + waitForJobExecutionTimeout, + numberOfExecutions = 2 +) => { + cy.log( + `Trying to provide at least ${numberOfExecutions} executions for Job "${jobName}"` + ); + + return _getJobExecutions(teamName, jobName).then((executions) => { + cy.log( + `Found ${executions.length} executions for Job "${jobName}" and target is ${numberOfExecutions} executions` + ); + + if (executions.length >= numberOfExecutions) { + cy.log( + `Skipping manual execution, expected number of executions found` + ); - return waitForJobExecutionCompletion(teamName, jobName, waitForJobExecutionTimeout) - .then(() => { - return _getJobLastDeployment(teamName, jobName) - .then((lastDeployment) => { - if (lastDeployment) { - return _executeCreateExecutionsForJob( - teamName, - jobName, - waitForJobExecutionTimeout, - lastDeployment, - executions, - numberOfExecutions - ); - } + return cy.wrap({ + context: "commands.helpers::1::createExecutionsForJob()", + action: "continue", + }); + } - return cy.wrap({ context: 'commands.helpers::2::createExecutionsForJob()', action: 'continue' }); - }); - }); + return waitForJobExecutionCompletion( + teamName, + jobName, + waitForJobExecutionTimeout + ).then(() => { + return _getJobLastDeployment(teamName, jobName).then( + (lastDeployment) => { + if (lastDeployment) { + return _executeCreateExecutionsForJob( + teamName, + jobName, + waitForJobExecutionTimeout, + lastDeployment, + executions, + numberOfExecutions + ); + } + + return cy.wrap({ + context: + "commands.helpers::2::createExecutionsForJob()", + action: "continue", + }); + } + ); }); + }); }; -const waitForJobExecutionCompletion = (teamName, jobName, jobExecutionTimeout, loopStep = 0) => { +const waitForJobExecutionCompletion = ( + teamName, + jobName, + jobExecutionTimeout, + loopStep = 0 +) => { const pollInterval = 5000; - return cy.request({ - url: Cypress.env('data_jobs_url') + `/data-jobs/for-team/${ teamName }/jobs/${ jobName }/executions`, - method: 'get', - auth: { - 'bearer': window.localStorage.getItem('access_token') - } - }).then((response) => { - if (response.status !== 200) { - cy.log(`Job execution poll failed. Status: ${ response.status }; Message: ${ response.body }`); - - return cy.wrap({ context: 'commands.helpers::1::waitForJobExecutionCompletion()', action: 'continue' }); - } - - const lastExecutions = response.body - .sort((left, right) => _compareDatesAsc(left, right)) - .slice(response.body.length > 5 ? response.body.length - 5 : 0); - - if (!lastExecutions.length || lastExecutions.length === 0) { - cy.log(`No valid Job executions available.`); + return cy + .request({ + url: + Cypress.env("data_jobs_url") + + `/data-jobs/for-team/${teamName}/jobs/${jobName}/executions`, + method: "get", + auth: { + bearer: window.localStorage.getItem("access_token"), + }, + }) + .then((response) => { + if (response.status !== 200) { + cy.log( + `Job execution poll failed. Status: ${response.status}; Message: ${response.body}` + ); + + return cy.wrap({ + context: + "commands.helpers::1::waitForJobExecutionCompletion()", + action: "continue", + }); + } - return cy.wrap({ context: 'commands.helpers::2::waitForJobExecutionCompletion()', action: 'continue' }); - } + const lastExecutions = response.body + .sort((left, right) => _compareDatesAsc(left, right)) + .slice(response.body.length > 5 ? response.body.length - 5 : 0); - const lastExecution = lastExecutions[lastExecutions.length - 1]; - const lastExecutionStatus = lastExecution.status.toLowerCase(); + if (!lastExecutions.length || lastExecutions.length === 0) { + cy.log(`No valid Job executions available.`); - if (lastExecutionStatus !== 'running' && lastExecutionStatus !== 'submitted') { - return ( - loopStep > 0 - ? cy.wait(pollInterval) - : cy.wrap({ context: 'commands.helpers::3::waitForJobExecutionCompletion()', action: 'continue' }) - ).then(() => { - cy.log(`Job "${ jobName }" executed successfully, polling completed!`); + return cy.wrap({ + context: + "commands.helpers::2::waitForJobExecutionCompletion()", + action: "continue", + }); + } - return cy.wrap({ context: 'commands.helpers::4::waitForJobExecutionCompletion()', action: 'continue' }); - }); - } + const lastExecution = lastExecutions[lastExecutions.length - 1]; + const lastExecutionStatus = lastExecution.status.toLowerCase(); + + if ( + lastExecutionStatus !== "running" && + lastExecutionStatus !== "submitted" + ) { + return ( + loopStep > 0 + ? cy.wait(pollInterval) + : cy.wrap({ + context: + "commands.helpers::3::waitForJobExecutionCompletion()", + action: "continue", + }) + ).then(() => { + cy.log( + `Job "${jobName}" executed successfully, polling completed!` + ); + + return cy.wrap({ + context: + "commands.helpers::4::waitForJobExecutionCompletion()", + action: "continue", + }); + }); + } - if (jobExecutionTimeout <= 0) { - cy.log('Time to wait exceeded! Will not wait for job execution to finish any longer.'); + if (jobExecutionTimeout <= 0) { + cy.log( + "Time to wait exceeded! Will not wait for job execution to finish any longer." + ); - return cy.wrap({ context: 'commands.helpers::5::waitForJobExecutionCompletion()', action: 'continue' }); - } + return cy.wrap({ + context: + "commands.helpers::5::waitForJobExecutionCompletion()", + action: "continue", + }); + } - cy.log(`Job ${ jobName }, still executing... Retrying after: ${ pollInterval / 1000 } seconds`); + cy.log( + `Job ${jobName}, still executing... Retrying after: ${ + pollInterval / 1000 + } seconds` + ); - return cy.wait(pollInterval) - .then(() => waitForJobExecutionCompletion(teamName, jobName, jobExecutionTimeout - pollInterval, jobExecutionTimeout++)) - }); + return cy + .wait(pollInterval) + .then(() => + waitForJobExecutionCompletion( + teamName, + jobName, + jobExecutionTimeout - pollInterval, + jobExecutionTimeout++ + ) + ); + }); }; const createTestJob = (testJob) => { let teamName = testJob.team; - return cy.request({ - // TODO: use jobsQuery - deprecated jobsList in favour of jobsQuery - url: Cypress.env('data_jobs_url') + `/data-jobs/for-team/${ teamName }/jobs`, - method: 'post', - body: testJob, - auth: { - 'bearer': window.localStorage.getItem('access_token') - }, - failOnStatusCode: false - }).then((response) => { - if (response.status >= 400) { - cy.log(`Http request fail for url:`, `/data-jobs/for-team/${ teamName }/jobs`); - - console.log(`Http request error:`, response); - } + return cy + .request({ + // TODO: use jobsQuery - deprecated jobsList in favour of jobsQuery + url: + Cypress.env("data_jobs_url") + + `/data-jobs/for-team/${teamName}/jobs`, + method: "post", + body: testJob, + auth: { + bearer: window.localStorage.getItem("access_token"), + }, + failOnStatusCode: false, + }) + .then((response) => { + if (response.status >= 400) { + cy.log( + `Http request fail for url:`, + `/data-jobs/for-team/${teamName}/jobs` + ); - return cy.wrap(response); - }); + console.log(`Http request error:`, response); + } + + return cy.wrap(response); + }); }; const deleteTestJobIfExists = (testJob) => { let teamName = testJob.team; let jobName = testJob.job_name; - return cy.request({ - url: Cypress.env('data_jobs_url') + `/data-jobs/for-team/${ teamName }/jobs/${ jobName }`, - method: 'get', - auth: { - 'bearer': window.localStorage.getItem('access_token') - }, - failOnStatusCode: false - }).then((outerResponse) => { - if (outerResponse.status === 200) { - return cy.request({ - url: Cypress.env('data_jobs_url') + `/data-jobs/for-team/${ teamName }/jobs/${ jobName }`, - method: 'delete', + return cy + .request({ + url: + Cypress.env("data_jobs_url") + + `/data-jobs/for-team/${teamName}/jobs/${jobName}`, + method: "get", + auth: { + bearer: window.localStorage.getItem("access_token"), + }, + failOnStatusCode: false, + }) + .then((outerResponse) => { + if (outerResponse.status === 200) { + return cy + .request({ + url: + Cypress.env("data_jobs_url") + + `/data-jobs/for-team/${teamName}/jobs/${jobName}`, + method: "delete", + auth: { + bearer: window.localStorage.getItem("access_token"), + }, + failOnStatusCode: false, + }) + .then((innerResponse) => { + if (innerResponse.status >= 400) { + cy.log( + `Http request fail for url:`, + `/data-jobs/for-team/${teamName}/jobs/${jobName}` + ); + + console.log(`Http request error:`, innerResponse); + } + + return cy.wrap({ + context: + "commands.helpers::1::deleteTestJobIfExists()", + action: "continue", + }); + }); + } else if (outerResponse.status >= 400) { + cy.log( + `Http request fail for url:`, + `/data-jobs/for-team/${teamName}/jobs/${jobName}` + ); + + console.log(`Http request error:`, outerResponse); + } + + return cy.wrap({ + context: "commands.helpers::2::deleteTestJobIfExists()", + action: "continue", + }); + }); +}; + +const deployTestJobIfNotExists = (pathToJobData, pathToJobBinary) => { + return cy.fixture(pathToJobData).then((testJob) => { + const normalizedTestJob = applyGlobalEnvSettings(testJob); + const teamName = normalizedTestJob.team; + const jobName = normalizedTestJob.job_name; + + // Check if data job exists and wether it has deployment or not. + return cy + .request({ + url: + Cypress.env("data_jobs_url") + + `/data-jobs/for-team/${teamName}/jobs/${jobName}/deployments`, + method: "get", auth: { - 'bearer': window.localStorage.getItem('access_token') + bearer: window.localStorage.getItem("access_token"), }, - failOnStatusCode: false - }).then((innerResponse) => { - if (innerResponse.status >= 400) { - cy.log(`Http request fail for url:`, `/data-jobs/for-team/${ teamName }/jobs/${ jobName }`); - - console.log(`Http request error:`, innerResponse); + failOnStatusCode: false, + }) + .then((outerResponse) => { + if ( + outerResponse.status === 200 && + outerResponse.body.length > 0 + ) { + cy.log( + jobName + + " is already existing, therefore skipping creation and deployment." + ); + } else if ( + outerResponse.status === 200 && + outerResponse.body.length === 0 + ) { + cy.log( + jobName + + " exists, but it is not deployed. Deploying..." + ); + + return _deployTestDataJob( + normalizedTestJob, + pathToJobBinary + ); + } else if (outerResponse.status === 404) { + return createTestJob(normalizedTestJob).then( + (innerResponse) => { + if (innerResponse.status === 201) { + return _deployTestDataJob( + normalizedTestJob, + pathToJobBinary + ); + } else { + throw new Error( + "Failed to create job: " + jobName + ); + } + } + ); + } else if (outerResponse.status >= 400) { + cy.log( + `Http request fail for url:`, + `/data-jobs/for-team/${teamName}/jobs/${jobName}/deployments` + ); + + console.log(`Http request error:`, outerResponse); } - return cy.wrap({ context: 'commands.helpers::1::deleteTestJobIfExists()', action: 'continue' }); + return cy.wrap({ + context: "commands.helpers::deployTestJobIfNotExists()", + action: "continue", + }); }); - } else if (outerResponse.status >= 400) { - cy.log(`Http request fail for url:`, `/data-jobs/for-team/${ teamName }/jobs/${ jobName }`); - - console.log(`Http request error:`, outerResponse); - } - - return cy.wrap({ context: 'commands.helpers::2::deleteTestJobIfExists()', action: 'continue' }); }); }; -const deployTestJobIfNotExists = (pathToJobData, pathToJobBinary) => { - return cy.fixture(pathToJobData) - .then((testJob) => { - const normalizedTestJob = applyGlobalEnvSettings(testJob); - const teamName = normalizedTestJob.team; - const jobName = normalizedTestJob.job_name; - - // Check if data job exists and wether it has deployment or not. - return cy.request({ - url: Cypress.env('data_jobs_url') + `/data-jobs/for-team/${ teamName }/jobs/${ jobName }/deployments`, - method: 'get', - auth: { - 'bearer': window.localStorage.getItem('access_token') - }, - failOnStatusCode: false - }).then((outerResponse) => { - if (outerResponse.status === 200 && outerResponse.body.length > 0) { - cy.log(jobName + ' is already existing, therefore skipping creation and deployment.'); - } else if (outerResponse.status === 200 && outerResponse.body.length === 0) { - cy.log(jobName + ' exists, but it is not deployed. Deploying...'); - - return _deployTestDataJob(normalizedTestJob, pathToJobBinary); - } else if (outerResponse.status === 404) { - return createTestJob(normalizedTestJob) - .then((innerResponse) => { - if (innerResponse.status === 201) { - return _deployTestDataJob(normalizedTestJob, pathToJobBinary); - } else { - throw new Error('Failed to create job: ' + jobName); - } - }); - } else if (outerResponse.status >= 400) { - cy.log(`Http request fail for url:`, `/data-jobs/for-team/${ teamName }/jobs/${ jobName }/deployments`); - - console.log(`Http request error:`, outerResponse); - } - - return cy.wrap({ context: 'commands.helpers::deployTestJobIfNotExists()', action: 'continue' }); - }); - }); -}; - function _loadTestEnvironmentVar() { - let testEnv = Cypress?.env('test_environment'); + let testEnv = Cypress?.env("test_environment"); if (!testEnv) { - console.log(`DataPipelines test_environment is not set. Using default: ${ DEFAULT_TEST_ENV_VAR }`); + console.log( + `DataPipelines test_environment is not set. Using default: ${DEFAULT_TEST_ENV_VAR}` + ); testEnv = DEFAULT_TEST_ENV_VAR; } return testEnv; } -function _executeCreateExecutionsForJob(teamName, jobName, waitForJobExecutionTimeout, lastDeployment, executions, numberOfExecutions, counterOfExecutions = 0) { +function _executeCreateExecutionsForJob( + teamName, + jobName, + waitForJobExecutionTimeout, + lastDeployment, + executions, + numberOfExecutions, + counterOfExecutions = 0 +) { const neededExecutions = numberOfExecutions - executions.length; if (counterOfExecutions === 0) { - cy.log(`Submitting ${ neededExecutions } serial executions`); + cy.log(`Submitting ${neededExecutions} serial executions`); } else { - cy.log(`${ neededExecutions - counterOfExecutions } more executions left for executing`) + cy.log( + `${ + neededExecutions - counterOfExecutions + } more executions left for executing` + ); } if (neededExecutions === counterOfExecutions) { - return cy.wrap({ context: 'commands.helpers::1::_executeCreateExecutionsForJob()', action: 'continue' }); + return cy.wrap({ + context: "commands.helpers::1::_executeCreateExecutionsForJob()", + action: "continue", + }); } return _executeJob(teamName, jobName, lastDeployment.id) .then(() => { - return cy.wait(5000) - .then(() => cy.wrap({ context: 'commands.helpers::2::_executeCreateExecutionsForJob()', action: 'continue' })); + return cy.wait(5000).then(() => + cy.wrap({ + context: + "commands.helpers::2::_executeCreateExecutionsForJob()", + action: "continue", + }) + ); }) .then(() => { - return waitForJobExecutionCompletion(teamName, jobName, waitForJobExecutionTimeout); + return waitForJobExecutionCompletion( + teamName, + jobName, + waitForJobExecutionTimeout + ); }) .then(() => { return _executeCreateExecutionsForJob( @@ -270,45 +424,49 @@ function _executeCreateExecutionsForJob(teamName, jobName, waitForJobExecutionTi } function _getJobExecutions(teamName, jobName) { - cy.log(`Fetching Job executions for Job "${ jobName }"`); + cy.log(`Fetching Job executions for Job "${jobName}"`); return cy .request({ - url: `/data-jobs/for-team/${ teamName }/jobs/${ jobName }/executions`, - method: 'get', + url: `/data-jobs/for-team/${teamName}/jobs/${jobName}/executions`, + method: "get", auth: { - 'bearer': window.localStorage.getItem('access_token') - } + bearer: window.localStorage.getItem("access_token"), + }, }) .then((response) => { if (response.status !== 200) { - cy.log(`Getting Job executions failed. Status: ${ response.status }; Message: ${ response.body }`); + cy.log( + `Getting Job executions failed. Status: ${response.status}; Message: ${response.body}` + ); return cy.wrap([]); } return cy.wrap( - response.body && response.body.length - ? response.body - : [] + response.body && response.body.length ? response.body : [] ); }); } function _getJobLastDeployment(teamName, jobName) { - cy.log(`Fetching Job deployments for Job "${ jobName }"`); + cy.log(`Fetching Job deployments for Job "${jobName}"`); return cy .request({ - url: Cypress.env('data_jobs_url') + `/data-jobs/for-team/${ teamName }/jobs/${ jobName }/deployments`, - method: 'get', + url: + Cypress.env("data_jobs_url") + + `/data-jobs/for-team/${teamName}/jobs/${jobName}/deployments`, + method: "get", auth: { - 'bearer': window.localStorage.getItem('access_token') - } + bearer: window.localStorage.getItem("access_token"), + }, }) .then((response) => { if (response.status !== 200) { - cy.log(`Getting Job deployments failed. Status: ${ response.status }; Message: ${ response.body }`); + cy.log( + `Getting Job deployments failed. Status: ${response.status}; Message: ${response.body}` + ); return cy.wrap(null); } @@ -322,29 +480,40 @@ function _getJobLastDeployment(teamName, jobName) { } function _executeJob(teamName, jobName, deploymentId) { - cy.log(`Submitting execution for Job "${ jobName }"`); - - return cy.request({ - url: Cypress.env('data_jobs_url') + `/data-jobs/for-team/${ teamName }/jobs/${ jobName }/deployments/${ deploymentId }/executions`, - method: 'post', - auth: { - 'bearer': window.localStorage.getItem('access_token') - }, - body: {} - }).then((response) => { - if (response.status >= 400) { - cy.log(`Executing Job failed. Status: ${ response.status }; Message: ${ response.body }`); - } + cy.log(`Submitting execution for Job "${jobName}"`); - return cy.wrap({ context: 'commands.helpers::_executeJob()', action: 'continue' }); - }); + return cy + .request({ + url: + Cypress.env("data_jobs_url") + + `/data-jobs/for-team/${teamName}/jobs/${jobName}/deployments/${deploymentId}/executions`, + method: "post", + auth: { + bearer: window.localStorage.getItem("access_token"), + }, + body: {}, + }) + .then((response) => { + if (response.status >= 400) { + cy.log( + `Executing Job failed. Status: ${response.status}; Message: ${response.body}` + ); + } + + return cy.wrap({ + context: "commands.helpers::_executeJob()", + action: "continue", + }); + }); } function _compareDatesAsc(left, right) { const leftStartTime = left.start_time ? left.start_time : 0; const rightStartTime = right.start_time ? right.start_time : 0; - return new Date(leftStartTime).getTime() - new Date(rightStartTime).getTime(); + return ( + new Date(leftStartTime).getTime() - new Date(rightStartTime).getTime() + ); } function _deployTestDataJob(testJob, pathToJobBinary) { @@ -352,44 +521,69 @@ function _deployTestDataJob(testJob, pathToJobBinary) { const jobName = testJob.job_name; const waitForJobDeploymentTimeout = 300000; // Wait up to 5 min for deployment to complete. - cy.log(`Deploying Job ${ jobName }`); + cy.log(`Deploying Job ${jobName}`); // Upload Data Job code - return cy.fixture(pathToJobBinary, 'binary') - .then((zippedDataJob) => { - return cy.request({ - url: Cypress.env('data_jobs_url') + '/data-jobs/for-team/' + teamName + '/jobs/' + jobName + '/sources', - method: 'post', - auth: { - 'bearer': window.localStorage.getItem('access_token') - }, - body: Cypress.Blob.binaryStringToBlob(zippedDataJob) - }).then((response1) => { - let jsonResponse = JSON.parse(Cypress.Blob.arrayBufferToBinaryString(response1.body)); - - // Deploy data job - return cy.request({ - url: Cypress.env('data_jobs_url') + '/data-jobs/for-team/' + teamName + '/jobs/' + jobName + '/deployments', - method: 'post', - auth: { - 'bearer': window.localStorage.getItem('access_token') - }, - body: { - job_version: jsonResponse.version_sha, - mode: 'release', - enabled: true - } - }).then((response2) => { - if (response2.status === 202) { - cy.log(`Job: ${ jobName } deployment in progress. Waiting for deployment to complete`); - - return _waitForDeploymentToFinish(testJob, waitForJobDeploymentTimeout); - } - - return cy.wrap({ context: 'commands.helpers::_deployTestDataJob()', action: 'continue' }); - }); - }); - }); + return cy.fixture(pathToJobBinary, "binary").then((zippedDataJob) => { + return cy + .request({ + url: + Cypress.env("data_jobs_url") + + "/data-jobs/for-team/" + + teamName + + "/jobs/" + + jobName + + "/sources", + method: "post", + auth: { + bearer: window.localStorage.getItem("access_token"), + }, + body: Cypress.Blob.binaryStringToBlob(zippedDataJob), + }) + .then((response1) => { + let jsonResponse = JSON.parse( + Cypress.Blob.arrayBufferToBinaryString(response1.body) + ); + + // Deploy data job + return cy + .request({ + url: + Cypress.env("data_jobs_url") + + "/data-jobs/for-team/" + + teamName + + "/jobs/" + + jobName + + "/deployments", + method: "post", + auth: { + bearer: window.localStorage.getItem("access_token"), + }, + body: { + job_version: jsonResponse.version_sha, + mode: "release", + enabled: true, + }, + }) + .then((response2) => { + if (response2.status === 202) { + cy.log( + `Job: ${jobName} deployment in progress. Waiting for deployment to complete` + ); + + return _waitForDeploymentToFinish( + testJob, + waitForJobDeploymentTimeout + ); + } + + return cy.wrap({ + context: "commands.helpers::_deployTestDataJob()", + action: "continue", + }); + }); + }); + }); } function _waitForDeploymentToFinish(testJob, timeout) { @@ -397,30 +591,55 @@ function _waitForDeploymentToFinish(testJob, timeout) { const jobName = testJob.job_name; const waitInterval = 5000; - return cy.request({ - url: Cypress.env('data_jobs_url') + '/data-jobs/for-team/' + teamName + '/jobs/' + jobName + '/deployments', - method: 'get', - auth: { - 'bearer': window.localStorage.getItem('access_token') - } - }).then((resp) => { - if (resp.status === 200 && resp.body.length > 0) { - cy.log('Job deployment finished!'); - - return cy.wrap({ context: 'commands.helpers::1::_waitForDeploymentToFinish()', action: 'continue' }); - } + return cy + .request({ + url: + Cypress.env("data_jobs_url") + + "/data-jobs/for-team/" + + teamName + + "/jobs/" + + jobName + + "/deployments", + method: "get", + auth: { + bearer: window.localStorage.getItem("access_token"), + }, + }) + .then((resp) => { + if (resp.status === 200 && resp.body.length > 0) { + cy.log("Job deployment finished!"); + + return cy.wrap({ + context: + "commands.helpers::1::_waitForDeploymentToFinish()", + action: "continue", + }); + } - if (timeout <= 0) { - cy.log('Time to wait exceeded! Will not wait for job deployment to finish any longer.'); + if (timeout <= 0) { + cy.log( + "Time to wait exceeded! Will not wait for job deployment to finish any longer." + ); - return cy.wrap({ context: 'commands.helpers::2::_waitForDeploymentToFinish()', action: 'continue' }); - } + return cy.wrap({ + context: + "commands.helpers::2::_waitForDeploymentToFinish()", + action: "continue", + }); + } - cy.log(`Job ${ jobName }, still not deployed.. retrying after: ${ waitInterval / 1000 } seconds`); + cy.log( + `Job ${jobName}, still not deployed.. retrying after: ${ + waitInterval / 1000 + } seconds` + ); - return cy.wait(waitInterval) - .then(() => _waitForDeploymentToFinish(testJob, timeout - waitInterval)); - }) + return cy + .wait(waitInterval) + .then(() => + _waitForDeploymentToFinish(testJob, timeout - waitInterval) + ); + }); } module.exports = { @@ -429,5 +648,5 @@ module.exports = { waitForJobExecutionCompletion, createTestJob, deleteTestJobIfExists, - deployTestJobIfNotExists + deployTestJobIfNotExists, }; diff --git a/projects/frontend/data-pipelines/gui/e2e/support/index.js b/projects/frontend/data-pipelines/gui/e2e/support/index.js index dfe8fbb0bc..ff4fb03a64 100644 --- a/projects/frontend/data-pipelines/gui/e2e/support/index.js +++ b/projects/frontend/data-pipelines/gui/e2e/support/index.js @@ -3,16 +3,16 @@ * SPDX-License-Identifier: Apache-2.0 */ -import './commands' +import "./commands"; -require('@neuralegion/cypress-har-generator/commands'); -require('cypress-grep')(); -require('cypress-terminal-report/src/installLogsCollector')(); +require("@neuralegion/cypress-har-generator/commands"); +require("cypress-grep")(); +require("cypress-terminal-report/src/installLogsCollector")(); Cypress.Server.defaults({ delay: 500, force404: false, ignore: (xhr) => { return true; - } -}) + }, +}); diff --git a/projects/frontend/data-pipelines/gui/e2e/support/pages/app/app.po.js b/projects/frontend/data-pipelines/gui/e2e/support/pages/app/app.po.js index 6a0e3e6cbb..d584a5afc9 100644 --- a/projects/frontend/data-pipelines/gui/e2e/support/pages/app/app.po.js +++ b/projects/frontend/data-pipelines/gui/e2e/support/pages/app/app.po.js @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { DataPipelinesBasePO } from '../../application/data-pipelines-base.po'; +import { DataPipelinesBasePO } from "../../application/data-pipelines-base.po"; export class AppPage extends DataPipelinesBasePO { static getPage() { @@ -11,10 +11,10 @@ export class AppPage extends DataPipelinesBasePO { } static navigateTo() { - cy.visit('/'); + cy.visit("/"); } getMainTitle() { - return cy.get('[data-cy=app-main-title]'); + return cy.get("[data-cy=app-main-title]"); } } diff --git a/projects/frontend/data-pipelines/gui/e2e/support/pages/app/getting-started/data-jobs-health-panel-component.po.js b/projects/frontend/data-pipelines/gui/e2e/support/pages/app/getting-started/data-jobs-health-panel-component.po.js index 13fcc897f5..29382d60fd 100644 --- a/projects/frontend/data-pipelines/gui/e2e/support/pages/app/getting-started/data-jobs-health-panel-component.po.js +++ b/projects/frontend/data-pipelines/gui/e2e/support/pages/app/getting-started/data-jobs-health-panel-component.po.js @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { GettingStartedPage } from './getting-started.po'; +import { GettingStartedPage } from "./getting-started.po"; export class DataJobsHealthPanelComponentPO extends GettingStartedPage { /** @@ -21,7 +21,7 @@ export class DataJobsHealthPanelComponentPO extends GettingStartedPage { * @returns {Cypress.Chainable>} */ getExecutionStatusGaugeWidget() { - return cy.get('[data-cy=dp-data-jobs-status-gauge-widget]'); + return cy.get("[data-cy=dp-data-jobs-status-gauge-widget]"); } /** @@ -31,11 +31,11 @@ export class DataJobsHealthPanelComponentPO extends GettingStartedPage { */ getExecutionsSuccessPercentage() { return this.getExecutionStatusGaugeWidget() - .should('exist') - .find('[data-cy=dp-jobs-executions-status-gauge-widget-percentage]') - .invoke('text') - .invoke('replace', /%/, '') - .then((value) => +value); + .should("exist") + .find("[data-cy=dp-jobs-executions-status-gauge-widget-percentage]") + .invoke("text") + .invoke("replace", /%/, "") + .then((value) => +value); } /** @@ -45,11 +45,11 @@ export class DataJobsHealthPanelComponentPO extends GettingStartedPage { */ getNumberOfFailedExecutions() { return this.getExecutionStatusGaugeWidget() - .should('exist') - .find('[data-cy=dp-jobs-executions-status-gauge-widget-failed]') - .invoke('text') - .invoke('replace', /\s\w+/, '') - .then((value) => +value); + .should("exist") + .find("[data-cy=dp-jobs-executions-status-gauge-widget-failed]") + .invoke("text") + .invoke("replace", /\s\w+/, "") + .then((value) => +value); } /** @@ -59,11 +59,11 @@ export class DataJobsHealthPanelComponentPO extends GettingStartedPage { */ getExecutionsTotal() { return this.getExecutionStatusGaugeWidget() - .should('exist') - .find('[data-cy=dp-jobs-executions-status-gauge-widget-total]') - .invoke('text') - .invoke('replace', /\s\w+/, '') - .then((value) => +value); + .should("exist") + .find("[data-cy=dp-jobs-executions-status-gauge-widget-total]") + .invoke("text") + .invoke("replace", /\s\w+/, "") + .then((value) => +value); } /** @@ -72,7 +72,7 @@ export class DataJobsHealthPanelComponentPO extends GettingStartedPage { * @returns {Cypress.Chainable>} */ getFailingJobsWidget() { - return cy.get('[data-cy=dp-failed-data-jobs-widget]'); + return cy.get("[data-cy=dp-failed-data-jobs-widget]"); } /** @@ -82,8 +82,8 @@ export class DataJobsHealthPanelComponentPO extends GettingStartedPage { */ getAllFailingJobs() { return this.getFailingJobsWidget() - .should('exist') - .find('[data-cy=dp-failed-data-jobs-widget-job-name-link]'); + .should("exist") + .find("[data-cy=dp-failed-data-jobs-widget-job-name-link]"); } /** @@ -92,7 +92,7 @@ export class DataJobsHealthPanelComponentPO extends GettingStartedPage { * @returns {Cypress.Chainable>} */ getMostRecentFailingJobsExecutionsWidget() { - return cy.get('[data-cy=dp-failed-data-jobs-executions-widget]'); + return cy.get("[data-cy=dp-failed-data-jobs-executions-widget]"); } /** @@ -102,18 +102,16 @@ export class DataJobsHealthPanelComponentPO extends GettingStartedPage { */ getAllMostRecentFailingJobsExecutions() { return this.getMostRecentFailingJobsExecutionsWidget() - .should('exist') - .find('[data-cy=dp-failed-data-jobs-executions-widget-job-name-link]'); + .should("exist") + .find( + "[data-cy=dp-failed-data-jobs-executions-widget-job-name-link]" + ); } // Actions navigateToFailingJobDetails(jobName) { - this._navigateToDataJob( - this.getAllFailingJobs(), - jobName, - 3 - ); + this._navigateToDataJob(this.getAllFailingJobs(), jobName, 3); } navigateToMostRecentFailingJobExecutions(jobName) { @@ -149,7 +147,7 @@ export class DataJobsHealthPanelComponentPO extends GettingStartedPage { return foundElement; }) - .should('exist') + .should("exist") .click({ force: true }); this.waitForBackendRequestCompletion(numberOfReqToWait); diff --git a/projects/frontend/data-pipelines/gui/e2e/support/pages/app/getting-started/getting-started.po.js b/projects/frontend/data-pipelines/gui/e2e/support/pages/app/getting-started/getting-started.po.js index 0f23a016bb..69c02c5bb9 100644 --- a/projects/frontend/data-pipelines/gui/e2e/support/pages/app/getting-started/getting-started.po.js +++ b/projects/frontend/data-pipelines/gui/e2e/support/pages/app/getting-started/getting-started.po.js @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { DataPipelinesBasePO } from '../../../application/data-pipelines-base.po'; +import { DataPipelinesBasePO } from "../../../application/data-pipelines-base.po"; export class GettingStartedPage extends DataPipelinesBasePO { /** @@ -12,7 +12,7 @@ export class GettingStartedPage extends DataPipelinesBasePO { * @returns {GettingStartedPage} */ static navigateTo() { - cy.visit('/get-started'); + cy.visit("/get-started"); this.waitForBackendRequestCompletion(3); @@ -36,7 +36,7 @@ export class GettingStartedPage extends DataPipelinesBasePO { * @returns {Cypress.Chainable>} */ getMainTitle() { - return cy.get('[data-cy=getting-started-main-title]'); + return cy.get("[data-cy=getting-started-main-title]"); } /** @@ -45,6 +45,6 @@ export class GettingStartedPage extends DataPipelinesBasePO { * @returns {Cypress.Chainable>} */ getDataJobsHealthPanel() { - return cy.get('[data-cy=dp-data-jobs-health-panel]'); + return cy.get("[data-cy=dp-data-jobs-health-panel]"); } } diff --git a/projects/frontend/data-pipelines/gui/e2e/support/pages/app/lib/explore/data-job-details.po.js b/projects/frontend/data-pipelines/gui/e2e/support/pages/app/lib/explore/data-job-details.po.js index 222bdee83a..9b0a6ab317 100644 --- a/projects/frontend/data-pipelines/gui/e2e/support/pages/app/lib/explore/data-job-details.po.js +++ b/projects/frontend/data-pipelines/gui/e2e/support/pages/app/lib/explore/data-job-details.po.js @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { DataJobDetailsBasePO } from '../../../../application/data-job-details-base.po'; +import { DataJobDetailsBasePO } from "../../../../application/data-job-details-base.po"; export class DataJobExploreDetailsPage extends DataJobDetailsBasePO { static getPage() { @@ -11,6 +11,6 @@ export class DataJobExploreDetailsPage extends DataJobDetailsBasePO { } static navigateTo(teamName, jobName) { - return super.navigateTo('explore', teamName, jobName); + return super.navigateTo("explore", teamName, jobName); } } diff --git a/projects/frontend/data-pipelines/gui/e2e/support/pages/app/lib/explore/data-jobs.po.js b/projects/frontend/data-pipelines/gui/e2e/support/pages/app/lib/explore/data-jobs.po.js index 373f0c96e4..48db089e76 100644 --- a/projects/frontend/data-pipelines/gui/e2e/support/pages/app/lib/explore/data-jobs.po.js +++ b/projects/frontend/data-pipelines/gui/e2e/support/pages/app/lib/explore/data-jobs.po.js @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { DataJobsBasePO } from '../../../../application/data-jobs-base.po'; +import { DataJobsBasePO } from "../../../../application/data-jobs-base.po"; export class DataJobsExplorePage extends DataJobsBasePO { static getPage() { @@ -11,44 +11,53 @@ export class DataJobsExplorePage extends DataJobsBasePO { } static navigateTo() { - return super.navigateTo('[data-cy=navigation-link-explore-datajobs]'); + return super.navigateTo("[data-cy=navigation-link-explore-datajobs]"); } // Selectors getMainTitle() { - return cy.get('[data-cy=data-pipelines-explore-page-main-title]'); + return cy.get("[data-cy=data-pipelines-explore-page-main-title]"); } getDataGrid() { - return cy.get('[data-cy=data-pipelines-explore-grid]'); + return cy.get("[data-cy=data-pipelines-explore-grid]"); } getDataGridCell(content) { - return cy.get('[id^="clr-dg-row"] > .datagrid-row-scrollable > .datagrid-scrolling-cells > .ng-star-inserted') - .contains(new RegExp(`^${ content }$`)); + return cy + .get( + '[id^="clr-dg-row"] > .datagrid-row-scrollable > .datagrid-scrolling-cells > .ng-star-inserted' + ) + .contains(new RegExp(`^${content}$`)); } getDataGridNavigateBtn(team, job) { - return cy.get('[data-cy=data-pipelines-explore-grid-details-link][data-job-params="' + team + ';' + job + '"]'); + return cy.get( + '[data-cy=data-pipelines-explore-grid-details-link][data-job-params="' + + team + + ";" + + job + + '"]' + ); } getDataGridNameFilter() { return this.getHeaderColumnJobName() - .should('exist') - .find('clr-dg-filter button'); + .should("exist") + .find("clr-dg-filter button"); } getDataGridNameFilterInput() { - return cy.get('div.datagrid-filter input'); + return cy.get("div.datagrid-filter input"); } getDataGridRefreshButton() { - return cy.get('[data-cy=data-pipelines-explore-refresh-btn]'); + return cy.get("[data-cy=data-pipelines-explore-refresh-btn]"); } getDataGridSearchInput() { - return cy.get('[data-test-id=search-input]'); + return cy.get("[data-test-id=search-input]"); } getDataGridClearSearchButton() { @@ -59,7 +68,7 @@ export class DataJobsExplorePage extends DataJobsBasePO { refreshDataGrid() { this.getDataGridRefreshButton() - .should('be.visible') + .should("be.visible") .click({ force: true }); this.waitForBackendRequestCompletion(); @@ -68,9 +77,7 @@ export class DataJobsExplorePage extends DataJobsBasePO { } searchByJobName(jobName) { - this.getDataGridSearchInput() - .should('be.visible') - .type(jobName); + this.getDataGridSearchInput().should("be.visible").type(jobName); this.waitForBackendRequestCompletion(); @@ -78,9 +85,7 @@ export class DataJobsExplorePage extends DataJobsBasePO { } clearSearchField() { - this.getDataGridSearchInput() - .should('be.visible') - .clear(); + this.getDataGridSearchInput().should("be.visible").clear(); this.waitForBackendRequestCompletion(); @@ -89,7 +94,7 @@ export class DataJobsExplorePage extends DataJobsBasePO { clearSearchFieldWithButton() { this.getDataGridClearSearchButton() - .should('be.visible') + .should("be.visible") .click({ force: true }); this.waitForBackendRequestCompletion(); @@ -98,16 +103,11 @@ export class DataJobsExplorePage extends DataJobsBasePO { } filterByJobName(jobName) { - this.getDataGridNameFilter() - .click({ force: true }); + this.getDataGridNameFilter().click({ force: true }); - this.getDataGridNameFilterInput() - .should('be.visible') - .type(jobName); + this.getDataGridNameFilterInput().should("be.visible").type(jobName); - this.getMainTitle() - .should('be.visible') - .click({ force: true }); + this.getMainTitle().should("be.visible").click({ force: true }); this.waitForBackendRequestCompletion(); @@ -117,7 +117,7 @@ export class DataJobsExplorePage extends DataJobsBasePO { openJobDetails(team, jobName) { this.getDataGridNavigateBtn(team, jobName) .scrollIntoView() - .should('exist') + .should("exist") .click({ force: true }); this.waitForBackendRequestCompletion(); diff --git a/projects/frontend/data-pipelines/gui/e2e/support/pages/app/lib/manage/data-job-details.po.js b/projects/frontend/data-pipelines/gui/e2e/support/pages/app/lib/manage/data-job-details.po.js index f0ac3c8b2b..f5be50cc34 100644 --- a/projects/frontend/data-pipelines/gui/e2e/support/pages/app/lib/manage/data-job-details.po.js +++ b/projects/frontend/data-pipelines/gui/e2e/support/pages/app/lib/manage/data-job-details.po.js @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { DataJobDetailsBasePO } from '../../../../application/data-job-details-base.po'; +import { DataJobDetailsBasePO } from "../../../../application/data-job-details-base.po"; export class DataJobManageDetailsPage extends DataJobDetailsBasePO { static getPage() { @@ -11,113 +11,126 @@ export class DataJobManageDetailsPage extends DataJobDetailsBasePO { } static navigateTo(teamName, jobName) { - return super.navigateTo('manage', teamName, jobName); + return super.navigateTo("manage", teamName, jobName); } // Deployment methods // Acceptable values are "not-deployed", "enabled", "disabled" getDeploymentStatus(status) { - return cy.get('[data-cy=data-pipelines-job-details-status-' + status + ']'); + return cy.get( + "[data-cy=data-pipelines-job-details-status-" + status + "]" + ); } // Description methods getDescription() { - return cy.get('[data-cy=data-pipelines-data-job-details-description] .form-section-readonly'); + return cy.get( + "[data-cy=data-pipelines-data-job-details-description] .form-section-readonly" + ); } getDescriptionEditButton() { - return cy.get('[data-cy=data-pipelines-data-job-details-description] .form-section-header > .btn'); + return cy.get( + "[data-cy=data-pipelines-data-job-details-description] .form-section-header > .btn" + ); } getDescriptionEditTextarea() { - return cy.get('[data-cy=data-pipelines-data-job-details-description] textarea'); + return cy.get( + "[data-cy=data-pipelines-data-job-details-description] textarea" + ); } getDescriptionSaveButton() { - return cy.get('[data-cy=data-pipelines-data-job-details-description] button:contains(Save)') + return cy.get( + "[data-cy=data-pipelines-data-job-details-description] button:contains(Save)" + ); } openDescription() { - this.getDescriptionEditButton() - .click({ force: true }); + this.getDescriptionEditButton().click({ force: true }); } enterDescriptionDetails(description) { - this.getDescriptionEditTextarea() - .clear() - .type(description) + this.getDescriptionEditTextarea().clear().type(description); } saveDescription() { - this.getDescriptionSaveButton() - .click({ force: true }); + this.getDescriptionSaveButton().click({ force: true }); - this.waitForBackendRequestCompletion() + this.waitForBackendRequestCompletion(); } // Schedule methods getSchedule() { - return cy.get('[data-cy=data-pipelines-data-job-details-schedule] .form-section-readonly'); + return cy.get( + "[data-cy=data-pipelines-data-job-details-schedule] .form-section-readonly" + ); } // Disable/Enable methods getStatusEditButton() { - return cy.get('[data-cy=data-pipelines-data-job-details-status] .form-section-header > .btn') + return cy.get( + "[data-cy=data-pipelines-data-job-details-status] .form-section-header > .btn" + ); } getStatusSaveButton() { - return cy.get('[data-cy=data-pipelines-data-job-details-status] button:contains(Save)'); + return cy.get( + "[data-cy=data-pipelines-data-job-details-status] button:contains(Save)" + ); } changeStatus(currentStatus) { - const newStatus = currentStatus.trim().toLowerCase() === 'enabled' - ? 'disable' - : 'enable'; - - return cy.get(`[data-cy=data-pipelines-data-job-details-status-${ newStatus }]`) - .should('exist') - .check({ force: true }); + const newStatus = + currentStatus.trim().toLowerCase() === "enabled" + ? "disable" + : "enable"; + + return cy + .get( + `[data-cy=data-pipelines-data-job-details-status-${newStatus}]` + ) + .should("exist") + .check({ force: true }); } toggleJobStatus() { - cy.get('[data-cy=data-pipelines-job-details-status]') - .invoke('text') - .then((jobStatus) => { - this.getStatusEditButton() - .scrollIntoView() - .click({ force: true }); + cy.get("[data-cy=data-pipelines-job-details-status]") + .invoke("text") + .then((jobStatus) => { + this.getStatusEditButton() + .scrollIntoView() + .click({ force: true }); - this.changeStatus(jobStatus); + this.changeStatus(jobStatus); - this.waitForClickThinkingTime(); + this.waitForClickThinkingTime(); - this.getStatusSaveButton() - .scrollIntoView() - .click({ force: true }); + this.getStatusSaveButton() + .scrollIntoView() + .click({ force: true }); - let newStatus = jobStatus === 'Enabled' - ? 'Disabled' - : 'Enabled'; + let newStatus = + jobStatus === "Enabled" ? "Disabled" : "Enabled"; - this.waitForBackendRequestCompletion(); + this.waitForBackendRequestCompletion(); - this.getToastTitle() - .should('exist') - .should('contain.text', 'Status update completed'); + this.getToastTitle() + .should("exist") + .should("contain.text", "Status update completed"); - this.waitForActionThinkingTime(); // Natural wait for User action + this.waitForActionThinkingTime(); // Natural wait for User action - this.getToastDismiss() - .should('exist') - .click({ force: true }); + this.getToastDismiss().should("exist").click({ force: true }); - cy.get('[data-cy=data-pipelines-job-details-status]') - .scrollIntoView() - .should('have.text', newStatus); - }) + cy.get("[data-cy=data-pipelines-job-details-status]") + .scrollIntoView() + .should("have.text", newStatus); + }); } } diff --git a/projects/frontend/data-pipelines/gui/e2e/support/pages/app/lib/manage/data-job-executions.po.js b/projects/frontend/data-pipelines/gui/e2e/support/pages/app/lib/manage/data-job-executions.po.js index af3c744c6a..9a4b7d80c9 100644 --- a/projects/frontend/data-pipelines/gui/e2e/support/pages/app/lib/manage/data-job-executions.po.js +++ b/projects/frontend/data-pipelines/gui/e2e/support/pages/app/lib/manage/data-job-executions.po.js @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { DataJobBasePO } from '../../../../application/data-job-base.po'; +import { DataJobBasePO } from "../../../../application/data-job-base.po"; export class DataJobManageExecutionsPage extends DataJobBasePO { static getPage() { @@ -11,7 +11,9 @@ export class DataJobManageExecutionsPage extends DataJobBasePO { } static navigateTo(teamName, jobName) { - return super.navigateToUrl(`/manage/data-jobs/${ teamName }/${ jobName }/executions`); + return super.navigateToUrl( + `/manage/data-jobs/${teamName}/${jobName}/executions` + ); } /* Utils */ @@ -23,12 +25,15 @@ export class DataJobManageExecutionsPage extends DataJobBasePO { * - val=45s */ convertStringContentToSeconds(val) { - const params = val.split(' '); + const params = val.split(" "); if (params.length === 2) { - return parseInt(params[0].trim().replace(/m$/, ''), 10) * 60 + parseInt(params[1].trim().replace(/s$/, ''), 10); + return ( + parseInt(params[0].trim().replace(/m$/, ""), 10) * 60 + + parseInt(params[1].trim().replace(/s$/, ""), 10) + ); } else { - return parseInt(params[0].trim().replace(/s$/, ''), 10); + return parseInt(params[0].trim().replace(/s$/, ""), 10); } } @@ -37,231 +42,241 @@ export class DataJobManageExecutionsPage extends DataJobBasePO { // General getExecRefreshBtn() { - return cy.get('[data-cy=data-pipelines-job-executions-refresh-btn'); + return cy.get("[data-cy=data-pipelines-job-executions-refresh-btn"); } getExecLoadingSpinner() { - return cy.get('[data-cy=data-pipelines-job-executions-loading-spinner]'); + return cy.get( + "[data-cy=data-pipelines-job-executions-loading-spinner]" + ); } // Charts getStatusChart() { - return cy.get('[data-cy=data-pipelines-job-executions-status-chart]'); + return cy.get("[data-cy=data-pipelines-job-executions-status-chart]"); } getDurationChart() { - return cy.get('[data-cy=data-pipelines-job-executions-duration-chart]'); + return cy.get("[data-cy=data-pipelines-job-executions-duration-chart]"); } getTimePeriod() { - return cy.get('[data-cy=data-pipelines-job-executions-time-period]'); + return cy.get("[data-cy=data-pipelines-job-executions-time-period]"); } // DataGrid getDataGrid() { - return cy.get('[data-cy=data-pipelines-job-executions-datagrid]'); + return cy.get("[data-cy=data-pipelines-job-executions-datagrid]"); } getDataGridPopupFilter() { - return cy.get('.datagrid-filter.clr-popover-content'); + return cy.get(".datagrid-filter.clr-popover-content"); } getDataGridInputFilter() { - return this.getDataGridPopupFilter() - .should('exist') - .find('input'); + return this.getDataGridPopupFilter().should("exist").find("input"); } getDataGridPopupFilterCloseBtn() { - return this.getDataGridPopupFilter() - .should('exist') - .find('.close'); + return this.getDataGridPopupFilter().should("exist").find(".close"); } getDataGridSpinner() { - return this.getDataGrid() - .should('exist') - .find('.datagrid-spinner'); + return this.getDataGrid().should("exist").find(".datagrid-spinner"); } // Header getDataGridExecStatusHeader() { return this.getDataGrid() - .should('exist') - .find('[data-cy=data-pipelines-job-executions-status-header]'); + .should("exist") + .find("[data-cy=data-pipelines-job-executions-status-header]"); } getDataGridExecStatusFilterOpenerBtn() { return this.getDataGridExecStatusHeader() - .should('exist') - .find('.datagrid-filter-toggle'); + .should("exist") + .find(".datagrid-filter-toggle"); } getDataGridExecStatusFilters() { return this.getDataGridPopupFilter() - .should('exist') - .find('[data-cy=data-pipelines-job-executions-status-filters]'); + .should("exist") + .find("[data-cy=data-pipelines-job-executions-status-filters]"); } getDataGridExecTypeHeader() { return this.getDataGrid() - .should('exist') - .find('[data-cy=data-pipelines-job-executions-type-header]'); + .should("exist") + .find("[data-cy=data-pipelines-job-executions-type-header]"); } getDataGridExecTypeFilterOpenerBtn() { return this.getDataGridExecTypeHeader() - .should('exist') - .find('.datagrid-filter-toggle'); + .should("exist") + .find(".datagrid-filter-toggle"); } getDataGridExecTypeFilters() { return this.getDataGridPopupFilter() - .should('exist') - .find('[data-cy=data-pipelines-job-executions-type-filters]'); + .should("exist") + .find("[data-cy=data-pipelines-job-executions-type-filters]"); } getDataGridExecDurationHeader() { return this.getDataGrid() - .should('exist') - .find('[data-cy=data-pipelines-job-executions-duration-header]'); + .should("exist") + .find("[data-cy=data-pipelines-job-executions-duration-header]"); } getDataGridExecDurationSortBtn() { return this.getDataGridExecDurationHeader() - .should('exist') - .find('.datagrid-column-title'); + .should("exist") + .find(".datagrid-column-title"); } getDataGridExecStartHeader() { return this.getDataGrid() - .should('exist') - .find('[data-cy=data-pipelines-job-executions-start-header]'); + .should("exist") + .find("[data-cy=data-pipelines-job-executions-start-header]"); } getDataGridExecStartSortBtn() { return this.getDataGridExecStartHeader() - .should('exist') - .find('.datagrid-column-title'); + .should("exist") + .find(".datagrid-column-title"); } getDataGridExecEndHeader() { return this.getDataGrid() - .should('exist') - .find('[data-cy=data-pipelines-job-executions-end-header]'); + .should("exist") + .find("[data-cy=data-pipelines-job-executions-end-header]"); } getDataGridExecEndSortBtn() { return this.getDataGridExecEndHeader() - .should('exist') - .find('.datagrid-column-title'); + .should("exist") + .find(".datagrid-column-title"); } getDataGridExecIDHeader() { return this.getDataGrid() - .should('exist') - .find('[data-cy=data-pipelines-job-executions-id-header]'); + .should("exist") + .find("[data-cy=data-pipelines-job-executions-id-header]"); } getDataGridExecIDFilterOpenerBtn() { return this.getDataGridExecIDHeader() - .should('exist') - .find('.datagrid-filter-toggle'); + .should("exist") + .find(".datagrid-filter-toggle"); } getDataGridExecVersionHeader() { return this.getDataGrid() - .should('exist') - .find('[data-cy=data-pipelines-job-executions-version-header]'); + .should("exist") + .find("[data-cy=data-pipelines-job-executions-version-header]"); } getDataGridExecVersionFilterOpenerBtn() { return this.getDataGridExecVersionHeader() - .should('exist') - .find('.datagrid-filter-toggle'); + .should("exist") + .find(".datagrid-filter-toggle"); } // Rows and Cells getDataGridRows() { return this.getDataGrid() - .should('exist') - .find('clr-dg-row.datagrid-row'); + .should("exist") + .find("clr-dg-row.datagrid-row"); } getDataGridRow(rowIndex) { return this.getDataGridRows() - .should('have.length.gte', rowIndex - 1) - .then((rows) => Array.from(rows)[rowIndex - 1]); + .should("have.length.gte", rowIndex - 1) + .then((rows) => Array.from(rows)[rowIndex - 1]); } getDataGridCells(rowIndex) { return this.getDataGridRow(rowIndex) - .should('exist') - .find('clr-dg-cell.datagrid-cell'); + .should("exist") + .find("clr-dg-cell.datagrid-cell"); } getDataGridCellByIndex(rowIndex, cellIndex) { if (rowIndex) { return this.getDataGridCells(rowIndex) - .should('have.length.gte', cellIndex - 1) - .then((cells) => Array.from(cells)[cellIndex - 1]); + .should("have.length.gte", cellIndex - 1) + .then((cells) => Array.from(cells)[cellIndex - 1]); } return this.getDataGridRows() - .should('have.length.gte', 0) - .then(($rows) => { - const _rows = $rows.reduce((accumulator, row) => { - const _cells = Array.from(row.querySelectorAll('clr-dg-cell.datagrid-cell')); + .should("have.length.gte", 0) + .then(($rows) => { + const _rows = $rows.reduce((accumulator, row) => { + const _cells = Array.from( + row.querySelectorAll("clr-dg-cell.datagrid-cell") + ); - if (_cells[cellIndex - 1]) { - accumulator.push(_cells[cellIndex - 1]); - } + if (_cells[cellIndex - 1]) { + accumulator.push(_cells[cellIndex - 1]); + } - return accumulator; - }, []); + return accumulator; + }, []); - return _rows; - }) + return _rows; + }); } getDataGridCellByIdentifier(rowIndex, identifier) { - return this.getDataGridRow(rowIndex) - .should('exist') - .find(identifier) + return this.getDataGridRow(rowIndex).should("exist").find(identifier); } getDataGridExecTypeCell(rowIndex) { - return this.getDataGridCellByIdentifier(rowIndex, '[data-cy=data-pipelines-job-executions-type-cell]'); + return this.getDataGridCellByIdentifier( + rowIndex, + "[data-cy=data-pipelines-job-executions-type-cell]" + ); } getDataGridExecTypeContainer(rowIndex) { return this.getDataGridExecTypeCell(rowIndex) - .should('exist') - .find('[data-cy=data-pipelines-job-executions-type-container]'); + .should("exist") + .find("[data-cy=data-pipelines-job-executions-type-container]"); } getDataGridExecDurationCell(rowIndex) { - return this.getDataGridCellByIdentifier(rowIndex, '[data-cy=data-pipelines-job-executions-duration-cell]'); + return this.getDataGridCellByIdentifier( + rowIndex, + "[data-cy=data-pipelines-job-executions-duration-cell]" + ); } getDataGridExecStartCell(rowIndex) { - return this.getDataGridCellByIdentifier(rowIndex, '[data-cy=data-pipelines-job-executions-start-cell]'); + return this.getDataGridCellByIdentifier( + rowIndex, + "[data-cy=data-pipelines-job-executions-start-cell]" + ); } getDataGridExecEndCell(rowIndex) { - return this.getDataGridCellByIdentifier(rowIndex, '[data-cy=data-pipelines-job-executions-end-cell]'); + return this.getDataGridCellByIdentifier( + rowIndex, + "[data-cy=data-pipelines-job-executions-end-cell]" + ); } // Pagination getDataGridPagination() { return this.getDataGrid() - .should('exist') - .find('[data-cy=data-pipelines-job-executions-datagrid-pagination]'); + .should("exist") + .find( + "[data-cy=data-pipelines-job-executions-datagrid-pagination]" + ); } /* Actions */ @@ -269,32 +284,26 @@ export class DataJobManageExecutionsPage extends DataJobBasePO { // General refreshExecData() { - this.getExecRefreshBtn() - .should('exist') - .click({ force: true }) + this.getExecRefreshBtn().should("exist").click({ force: true }); } // DataGrid typeToFilterInput(value) { - this.getDataGridInputFilter() - .should('exist') - .type(value); + this.getDataGridInputFilter().should("exist").type(value); this.waitForViewToRenderShort(); } clearFilterInput() { - this.getDataGridInputFilter() - .should('exist') - .clear({ force: true }); + this.getDataGridInputFilter().should("exist").clear({ force: true }); this.waitForViewToRenderShort(); } closeFilter() { this.getDataGridPopupFilterCloseBtn() - .should('exist') + .should("exist") .click({ force: true }); this.waitForViewToRenderShort(); @@ -304,7 +313,7 @@ export class DataJobManageExecutionsPage extends DataJobBasePO { openStatusFilter() { this.getDataGridExecStatusFilterOpenerBtn() - .should('exist') + .should("exist") .click({ force: true }); this.waitForViewToRenderShort(); @@ -312,7 +321,7 @@ export class DataJobManageExecutionsPage extends DataJobBasePO { openTypeFilter() { this.getDataGridExecTypeFilterOpenerBtn() - .should('exist') + .should("exist") .click({ force: true }); this.waitForViewToRenderShort(); @@ -320,7 +329,7 @@ export class DataJobManageExecutionsPage extends DataJobBasePO { openIDFilter() { this.getDataGridExecIDFilterOpenerBtn() - .should('exist') + .should("exist") .click({ force: true }); this.waitForViewToRenderShort(); @@ -328,7 +337,7 @@ export class DataJobManageExecutionsPage extends DataJobBasePO { openVersionFilter() { this.getDataGridExecVersionFilterOpenerBtn() - .should('exist') + .should("exist") .click({ force: true }); this.waitForViewToRenderShort(); @@ -336,7 +345,7 @@ export class DataJobManageExecutionsPage extends DataJobBasePO { sortByExecDuration() { this.getDataGridExecDurationSortBtn() - .should('exist') + .should("exist") .click({ force: true }); this.waitForViewToRenderShort(); @@ -344,16 +353,14 @@ export class DataJobManageExecutionsPage extends DataJobBasePO { sortByExecStart() { this.getDataGridExecStartSortBtn() - .should('exist') + .should("exist") .click({ force: true }); this.waitForViewToRenderShort(); } sortByExecEnd() { - this.getDataGridExecEndSortBtn() - .should('exist') - .click({ force: true }); + this.getDataGridExecEndSortBtn().should("exist").click({ force: true }); this.waitForViewToRenderShort(); } diff --git a/projects/frontend/data-pipelines/gui/e2e/support/pages/app/lib/manage/data-jobs.po.js b/projects/frontend/data-pipelines/gui/e2e/support/pages/app/lib/manage/data-jobs.po.js index 1de29752f5..7e4b099223 100644 --- a/projects/frontend/data-pipelines/gui/e2e/support/pages/app/lib/manage/data-jobs.po.js +++ b/projects/frontend/data-pipelines/gui/e2e/support/pages/app/lib/manage/data-jobs.po.js @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { DataJobsBasePO } from '../../../../application/data-jobs-base.po'; +import { DataJobsBasePO } from "../../../../application/data-jobs-base.po"; export class DataJobsManagePage extends DataJobsBasePO { static getPage() { @@ -11,36 +11,45 @@ export class DataJobsManagePage extends DataJobsBasePO { } static navigateTo() { - return super.navigateTo('[data-cy=navigation-link-manage-datajobs]'); + return super.navigateTo("[data-cy=navigation-link-manage-datajobs]"); } getPageTitle() { - return cy.get('[data-cy=data-pipelines-manage-page-main-title]'); + return cy.get("[data-cy=data-pipelines-manage-page-main-title]"); } getDataGrid() { - return cy.get('[data-cy=data-pipelines-manage-grid]'); + return cy.get("[data-cy=data-pipelines-manage-grid]"); } getDataGridCell(content, timeout) { - return cy.get('[id^="clr-dg-row"] > .datagrid-row-scrollable > .datagrid-scrolling-cells > .ng-star-inserted') - .contains(new RegExp(`^\\s*${ content }\\s*$`), { timeout: this.resolveTimeout(timeout) }); + return cy + .get( + '[id^="clr-dg-row"] > .datagrid-row-scrollable > .datagrid-scrolling-cells > .ng-star-inserted' + ) + .contains(new RegExp(`^\\s*${content}\\s*$`), { + timeout: this.resolveTimeout(timeout), + }); } getDataGridRow(jobName) { - cy.log(`Looking for Job row: ${ jobName }`); + cy.log(`Looking for Job row: ${jobName}`); - return this.getDataGridCell(jobName) - .parents('clr-dg-row'); + return this.getDataGridCell(jobName).parents("clr-dg-row"); } getDataGridNavigateBtn(team, job) { - return cy.get('[data-cy=data-pipelines-manage-grid-details-link][data-job-params="' + team + ';' + job + '"]'); + return cy.get( + '[data-cy=data-pipelines-manage-grid-details-link][data-job-params="' + + team + + ";" + + job + + '"]' + ); } getDataGridSearchInput() { - return cy.get('[data-test-id=search-input]') - .first(); + return cy.get("[data-test-id=search-input]").first(); } getDataGridClearSearchButton() { @@ -48,8 +57,7 @@ export class DataJobsManagePage extends DataJobsBasePO { } searchByJobName(jobName) { - this.getDataGridSearchInput() - .type(jobName); + this.getDataGridSearchInput().type(jobName); this.waitForBackendRequestCompletion(); @@ -57,9 +65,7 @@ export class DataJobsManagePage extends DataJobsBasePO { } clearSearchField() { - this.getDataGridSearchInput() - .should('be.visible') - .clear(); + this.getDataGridSearchInput().should("be.visible").clear(); this.waitForBackendRequestCompletion(); @@ -68,7 +74,7 @@ export class DataJobsManagePage extends DataJobsBasePO { clearSearchFieldWithButton() { this.getDataGridClearSearchButton() - .should('be.visible') + .should("be.visible") .click({ force: true }); this.waitForBackendRequestCompletion(); @@ -77,8 +83,9 @@ export class DataJobsManagePage extends DataJobsBasePO { } refreshDataGrid() { - cy.get('[data-cy=data-pipelines-manage-refresh-btn]') - .click({ force: true }); + cy.get("[data-cy=data-pipelines-manage-refresh-btn]").click({ + force: true, + }); this.waitForBackendRequestCompletion(); @@ -88,98 +95,91 @@ export class DataJobsManagePage extends DataJobsBasePO { openJobDetails(teamName, jobName) { this.getDataGridNavigateBtn(teamName, jobName) .scrollIntoView() - .should('exist') + .should("exist") .click({ force: true }); this.waitForBackendRequestCompletion(); this.waitForViewToRenderShort(); - cy.get('[data-cy=data-pipelines-job-page]') - .should('be.visible'); + cy.get("[data-cy=data-pipelines-job-page]").should("be.visible"); } selectRow(jobName) { this.getDataGridRow(jobName) - .find('.datagrid-select input') + .find(".datagrid-select input") .check({ force: true }); } getExecuteNowGridButton() { - return cy.get('[data-cy=data-pipelines-manage-grid-execute-btn]'); + return cy.get("[data-cy=data-pipelines-manage-grid-execute-btn]"); } changeStatus(newStatus) { - cy.get(`[data-cy=data-pipelines-job-${ newStatus }-btn]`) - .should('exist') - .should('be.enabled') - .click({ force: true }); + cy.get(`[data-cy=data-pipelines-job-${newStatus}-btn]`) + .should("exist") + .should("be.enabled") + .click({ force: true }); } getJobStatus(jobName) { - return this.getDataGridRow(jobName) - .then(($row) => { - if ($row.find('[data-cy=data-pipelines-job-disabled]').length) { - return 'disable'; - } + return this.getDataGridRow(jobName).then(($row) => { + if ($row.find("[data-cy=data-pipelines-job-disabled]").length) { + return "disable"; + } - if ($row.find('[data-cy=data-pipelines-job-enabled]').length) { - return 'enable'; - } + if ($row.find("[data-cy=data-pipelines-job-enabled]").length) { + return "enable"; + } - return 'not_deployed'; - }); + return "not_deployed"; + }); } toggleJobStatus(jobName) { this.selectRow(jobName); - this.getJobStatus(jobName) - .then((currentStatus) => { - if (currentStatus === 'not_deployed') { - throw new Error('Data job is not Deployed.'); - } + this.getJobStatus(jobName).then((currentStatus) => { + if (currentStatus === "not_deployed") { + throw new Error("Data job is not Deployed."); + } - const newStatus = currentStatus === 'enable' - ? 'disable' - : 'enable'; + const newStatus = currentStatus === "enable" ? "disable" : "enable"; - cy.log(`Current status: ${ currentStatus }, new status: ${ newStatus }`); + cy.log( + `Current status: ${currentStatus}, new status: ${newStatus}` + ); - this.changeStatus(newStatus) + this.changeStatus(newStatus); - this.confirmInConfirmDialog(); + this.confirmInConfirmDialog(); - this.getToastTitle() - .should('exist') - .should('contain.text', 'Status update completed'); + this.getToastTitle() + .should("exist") + .should("contain.text", "Status update completed"); - this.getToastDismiss() - .should('exist') - .click({ force: true }); + this.getToastDismiss().should("exist").click({ force: true }); - this.waitForClickThinkingTime(); // Natural wait for User action + this.waitForClickThinkingTime(); // Natural wait for User action - this.refreshDataGrid(); + this.refreshDataGrid(); - this.getJobStatus(jobName) - .then((changedStatus) => { - expect(changedStatus).to.equal(newStatus); - }); + this.getJobStatus(jobName).then((changedStatus) => { + expect(changedStatus).to.equal(newStatus); }); + }); } filterByJobName(jobName) { - cy.get('[data-cy=data-pipelines-jobs-name-column] > .datagrid-column-flex > clr-dg-string-filter.ng-star-inserted > clr-dg-filter > .datagrid-filter-toggle > cds-icon') - .click({ force: true }); + cy.get( + "[data-cy=data-pipelines-jobs-name-column] > .datagrid-column-flex > clr-dg-string-filter.ng-star-inserted > clr-dg-filter > .datagrid-filter-toggle > cds-icon" + ).click({ force: true }); - cy.get('div.datagrid-filter > input') - .should('be.visible') - .type(jobName); + cy.get("div.datagrid-filter > input") + .should("be.visible") + .type(jobName); - this.getPageTitle() - .should('be.visible') - .click({ force: true }); + this.getPageTitle().should("be.visible").click({ force: true }); this.waitForBackendRequestCompletion(); @@ -191,9 +191,7 @@ export class DataJobsManagePage extends DataJobsBasePO { this.waitForClickThinkingTime(); - this.getExecuteNowGridButton() - .should('exist') - .click({ force: true }); + this.getExecuteNowGridButton().should("exist").click({ force: true }); this.waitForViewToRenderShort(); diff --git a/projects/frontend/data-pipelines/gui/projects/data-pipelines/karma.conf.js b/projects/frontend/data-pipelines/gui/projects/data-pipelines/karma.conf.js index 37b77549e7..38c6958af6 100644 --- a/projects/frontend/data-pipelines/gui/projects/data-pipelines/karma.conf.js +++ b/projects/frontend/data-pipelines/gui/projects/data-pipelines/karma.conf.js @@ -6,17 +6,17 @@ // Karma configuration file, see link for more information // https://karma-runner.github.io/1.0/config/configuration-file.html -module.exports = function(config) { +module.exports = function (config) { config.set({ - basePath: '', - frameworks: ['jasmine', '@angular-devkit/build-angular'], + basePath: "", + frameworks: ["jasmine", "@angular-devkit/build-angular"], plugins: [ - require('karma-jasmine'), - require('karma-chrome-launcher'), - require('karma-jasmine-html-reporter'), - require('karma-junit-reporter'), - require('karma-coverage'), - require('@angular-devkit/build-angular/plugins/karma') + require("karma-jasmine"), + require("karma-chrome-launcher"), + require("karma-jasmine-html-reporter"), + require("karma-junit-reporter"), + require("karma-coverage"), + require("@angular-devkit/build-angular/plugins/karma"), ], client: { jasmine: { @@ -25,44 +25,50 @@ module.exports = function(config) { // for example, you can disable the random execution with `random: false` // or set a specific seed with `seed: 4321` }, - clearContext: false // leave Jasmine Spec Runner output visible in browser + clearContext: false, // leave Jasmine Spec Runner output visible in browser }, jasmineHtmlReporter: { - suppressAll: true // removes the duplicated traces + suppressAll: true, // removes the duplicated traces }, coverageReporter: { - dir: require('path').join(__dirname, '../../reports/coverage/data-pipelines-lib'), - subdir: '.', + dir: require("path").join( + __dirname, + "../../reports/coverage/data-pipelines-lib" + ), + subdir: ".", reporters: [ //Code coverage - output in HTML file and Console(to be parsed in the CI/CD badge) - { type: 'html' }, - { type: 'text-summary' }, - { type: 'lcovonly' } + { type: "html" }, + { type: "text-summary" }, + { type: "lcovonly" }, ], check: { global: { - lines: 80 - } - } + lines: 80, + }, + }, }, - reporters: ['progress', 'junit', 'coverage'], + reporters: ["progress", "junit", "coverage"], junitReporter: { - outputDir: require('path').join(__dirname, '../../reports/test-results/data-pipelines-lib'), - outputFile: 'unit-tests.xml', - useBrowserName: false + outputDir: require("path").join( + __dirname, + "../../reports/test-results/data-pipelines-lib" + ), + outputFile: "unit-tests.xml", + useBrowserName: false, }, port: 9876, colors: true, logLevel: config.LOG_INFO, autoWatch: true, - browsers: ['ChromeHeadless'], + browsers: ["ChromeHeadless"], customLaunchers: { ChromeHeadless_No_Sandbox: { - base: 'ChromeHeadless', - flags: ['--no-sandbox'] - } + base: "ChromeHeadless", + flags: ["--no-sandbox"], + }, }, singleRun: false, - restartOnFileChange: true + restartOnFileChange: true, }); }; diff --git a/projects/frontend/data-pipelines/gui/projects/data-pipelines/src/lib/components/base-grid/_data-jobs-base-grid.component.scss b/projects/frontend/data-pipelines/gui/projects/data-pipelines/src/lib/components/base-grid/_data-jobs-base-grid.component.scss index 996efccbfe..be143f485a 100644 --- a/projects/frontend/data-pipelines/gui/projects/data-pipelines/src/lib/components/base-grid/_data-jobs-base-grid.component.scss +++ b/projects/frontend/data-pipelines/gui/projects/data-pipelines/src/lib/components/base-grid/_data-jobs-base-grid.component.scss @@ -4,116 +4,116 @@ */ :host { - .label-link { - cursor: pointer; - } - - ::ng-deep { - lib-grid-action { - display: flex; - flex-direction: column; - - lib-quick-filters { - clr-icon { - margin-left: -5px; - margin-right: 3px; - margin-top: 1px; - - &.status-icon-enabled { - color: #5aa220; - } - - &.status-icon-disabled { - color: var(--clr-color-neutral-600); - } - } - } + .label-link { + cursor: pointer; } - clr-datagrid { - height: 100%; - - .datagrid-column, - .datagrid-cell { - &.column__min-width--xs { - min-width: 3.25rem; - } - - &.column__min-width--s { - min-width: 4.25rem; + ::ng-deep { + lib-grid-action { + display: flex; + flex-direction: column; + + lib-quick-filters { + clr-icon { + margin-left: -5px; + margin-right: 3px; + margin-top: 1px; + + &.status-icon-enabled { + color: #5aa220; + } + + &.status-icon-disabled { + color: var(--clr-color-neutral-600); + } + } + } } - &.column__min-width--m { - min-width: 4.8rem; - } - - &.column__min-width--l { - min-width: 5.5rem; - } - - &.column__min-width--xl { - min-width: 6.5rem; - } - - &.column__max-width--xs { - max-width: 5rem; - } - - &.column__max-width--s { - max-width: 6rem; - } - - &.column__max-width--m { - max-width: 7rem; - } - - &.column__max-width--l { - max-width: 8.5rem; - } - - &.column__max-width--xl { - max-width: 10rem; - } + clr-datagrid { + height: 100%; - &.jobs-list__column-opener { - min-width: 75px; - width: 75px; + .datagrid-column, + .datagrid-cell { + &.column__min-width--xs { + min-width: 3.25rem; + } + + &.column__min-width--s { + min-width: 4.25rem; + } + + &.column__min-width--m { + min-width: 4.8rem; + } + + &.column__min-width--l { + min-width: 5.5rem; + } + + &.column__min-width--xl { + min-width: 6.5rem; + } + + &.column__max-width--xs { + max-width: 5rem; + } + + &.column__max-width--s { + max-width: 6rem; + } + + &.column__max-width--m { + max-width: 7rem; + } + + &.column__max-width--l { + max-width: 8.5rem; + } + + &.column__max-width--xl { + max-width: 10rem; + } + + &.jobs-list__column-opener { + min-width: 75px; + width: 75px; + } + } + + .datagrid-outer-wrapper { + .datagrid-inner-wrapper { + .datagrid { + flex-basis: 0; + margin-top: 0; + } + + .datagrid-spinner { + top: 0; + height: 100%; + } + } + } } - } + } - .datagrid-outer-wrapper { - .datagrid-inner-wrapper { - .datagrid { - flex-basis: 0; - margin-top: 0; - } + .grid-container { + height: 100%; + display: flex; + flex-direction: column; - .datagrid-spinner { - top: 0; + .container { height: 100%; - } } - } - } - } - - .grid-container { - height: 100%; - display: flex; - flex-direction: column; - - .container { - height: 100%; } - } - .grid-container-compact { - height: auto; - display: flex; - flex-direction: column; + .grid-container-compact { + height: auto; + display: flex; + flex-direction: column; - .container-compact { - height: 50vh; + .container-compact { + height: 50vh; + } } - } } diff --git a/projects/frontend/data-pipelines/gui/projects/data-pipelines/src/lib/components/base-grid/data-jobs-base-grid.component.ts b/projects/frontend/data-pipelines/gui/projects/data-pipelines/src/lib/components/base-grid/data-jobs-base-grid.component.ts index e6142b05ee..1f0f223ebd 100644 --- a/projects/frontend/data-pipelines/gui/projects/data-pipelines/src/lib/components/base-grid/data-jobs-base-grid.component.ts +++ b/projects/frontend/data-pipelines/gui/projects/data-pipelines/src/lib/components/base-grid/data-jobs-base-grid.component.ts @@ -32,7 +32,7 @@ import { RouterState, RouteState, TaurusBaseComponent, - URLStateManager + URLStateManager, } from '@vdk/shared'; import { ErrorUtil } from '../../shared/utils'; @@ -46,7 +46,7 @@ import { DataPipelinesConfig, DataPipelinesRestoreUI, DisplayMode, - JOBS_DATA_KEY + JOBS_DATA_KEY, } from '../../model'; import { DataJobsApiService, DataJobsService } from '../../services'; @@ -69,8 +69,14 @@ export type DataJobsLocalStorageUserConfig = { @Directive() export abstract class DataJobsBaseGridComponent extends TaurusBaseComponent - implements OnInit, OnTaurusModelInit, OnTaurusModelInitialLoad, OnTaurusModelLoad, OnTaurusModelChange, OnTaurusModelError { - + implements + OnInit, + OnTaurusModelInit, + OnTaurusModelInitialLoad, + OnTaurusModelLoad, + OnTaurusModelChange, + OnTaurusModelError +{ static readonly UI_KEY_PAGE_OFFSET = 'pageOffset'; static readonly UI_KEY_GRID_OFFSET = 'gridOffset'; static readonly UI_KEY_GRID_UI_STATE = 'gridUIState'; @@ -78,7 +84,8 @@ export abstract class DataJobsBaseGridComponent static readonly CONTENT_AREA_SELECTOR = '.content-area'; static readonly DATA_GRID_SELECTOR = '.datagrid'; - @Input() urlUpdateStrategy: 'updateLocation' | 'updateRouter' = 'updateRouter'; + @Input() urlUpdateStrategy: 'updateLocation' | 'updateRouter' = + 'updateRouter'; @Input() searchParam: string = QUERY_PARAM_SEARCH; @Input() set urlStateManager(value: URLStateManager) { @@ -111,14 +118,14 @@ export abstract class DataJobsBaseGridComponent deploymentStatuses = [ DataJobStatus.ENABLED, DataJobStatus.DISABLED, - DataJobStatus.NOT_DEPLOYED + DataJobStatus.NOT_DEPLOYED, ]; executionStatuses = [ DataJobExecutionStatus.SUCCEEDED, DataJobExecutionStatus.PLATFORM_ERROR, DataJobExecutionStatus.USER_ERROR, DataJobExecutionStatus.SKIPPED, - DataJobExecutionStatus.CANCELLED + DataJobExecutionStatus.CANCELLED, ]; clrGridCurrentPage = 1; @@ -136,7 +143,8 @@ export abstract class DataJobsBaseGridComponent protected _urlStateManager: URLStateManager; private _isUrlStateManagerExternalDependency = false; - protected constructor( // NOSONAR + protected constructor( + // NOSONAR componentService: ComponentService, navigationService: NavigationService, activatedRoute: ActivatedRoute, @@ -164,11 +172,14 @@ export abstract class DataJobsBaseGridComponent * ** NgFor elements tracking function. */ trackByFn(index: number, dataJob: DataJob): string { - return `${ index }|${ dataJob?.config?.team }|${ dataJob?.jobName }`; + return `${index}|${dataJob?.config?.team}|${dataJob?.jobName}`; } resolveLogsUrl(job: DataJob): string { - if (CollectionsUtil.isNil(job) || CollectionsUtil.isArrayEmpty(job.deployments)) { + if ( + CollectionsUtil.isNil(job) || + CollectionsUtil.isArrayEmpty(job.deployments) + ) { return null; } @@ -181,7 +192,10 @@ export abstract class DataJobsBaseGridComponent showOrHideColumnChange(columnName: string, hidden: boolean): void { this.localStorageUserConfig.hiddenColumns[columnName] = hidden; - localStorage.setItem(this.localStorageConfigKey, JSON.stringify(this.localStorageUserConfig)); + localStorage.setItem( + this.localStorageConfigKey, + JSON.stringify(this.localStorageUserConfig) + ); } getJobStatus(job: DataJob): DataJobExecutionStatus { @@ -194,8 +208,10 @@ export abstract class DataJobsBaseGridComponent getJobSuccessRateTitle(job: DataJob): string { if (job.deployments) { - return `${ job.deployments[0]?.successfulExecutions } successful / ${ job.deployments[0]?.failedExecutions - + job.deployments[0]?.successfulExecutions } total`; + return `${job.deployments[0]?.successfulExecutions} successful / ${ + job.deployments[0]?.failedExecutions + + job.deployments[0]?.successfulExecutions + } total`; } return null; @@ -230,7 +246,9 @@ export abstract class DataJobsBaseGridComponent if (this.filterByTeamName && !this.teamNameFilter) { //While the teamNameFilter is empty, no refresh requests will be executed. - console.log('Refresh operation will be skipped. teamNameFilter is empty.'); + console.log( + 'Refresh operation will be skipped. teamNameFilter is empty.' + ); return; } @@ -254,18 +272,16 @@ export abstract class DataJobsBaseGridComponent this.saveUIState(); this.selectionChanged(job); - this.dataJobsService - .notifyForTeamImplicitly(job.config?.team); + this.dataJobsService.notifyForTeamImplicitly(job.config?.team); this.navigationInProgress = true; this.navigateTo({ '$.team': job.config?.team, - '$.job': job.jobName - }) - .finally(() => { - this.navigationInProgress = false; - }); + '$.job': job.jobName, + }).finally(() => { + this.navigationInProgress = false; + }); } } @@ -279,9 +295,12 @@ export abstract class DataJobsBaseGridComponent this.routerService .get() .pipe( - distinctUntilChanged((a, b) => - a.state.absoluteConfigPath !== b.state.absoluteConfigPath || - a.state.absoluteRoutePath === b.state.absoluteRoutePath + distinctUntilChanged( + (a, b) => + a.state.absoluteConfigPath !== + b.state.absoluteConfigPath || + a.state.absoluteRoutePath === + b.state.absoluteRoutePath ) ) .subscribe((routerState) => { @@ -300,9 +319,10 @@ export abstract class DataJobsBaseGridComponent if (this._shouldRestoreUIState(routerState)) { this.restoreUIStateInProgress = true; - const clrGridUIState = this.model.getUiState( - DataJobsBaseGridComponent.UI_KEY_GRID_UI_STATE - ); + const clrGridUIState = + this.model.getUiState( + DataJobsBaseGridComponent.UI_KEY_GRID_UI_STATE + ); if (clrGridUIState) { this.clrGridUIState = clrGridUIState; } @@ -328,9 +348,7 @@ export abstract class DataJobsBaseGridComponent onModelInitialLoad() { this.routerService .get() - .pipe( - take(1) - ) + .pipe(take(1)) .subscribe((routerState) => { if (this._shouldRestoreUIState(routerState)) { this.restoreUIState(); @@ -352,7 +370,8 @@ export abstract class DataJobsBaseGridComponent */ onModelChange(model: ComponentModel) { const componentState = model.getComponentState(); - const dataJobsData: { content: DataJob[], totalItems: number } = componentState.data.get(JOBS_DATA_KEY); + const dataJobsData: { content: DataJob[]; totalItems: number } = + componentState.data.get(JOBS_DATA_KEY); this.dataJobs = CollectionsUtil.isArray(dataJobsData?.content) ? [...dataJobsData?.content] @@ -365,9 +384,7 @@ export abstract class DataJobsBaseGridComponent * @inheritDoc */ onModelError(model?: ComponentModel) { - const error = ErrorUtil.extractError( - model.getComponentState().error - ); + const error = ErrorUtil.extractError(model.getComponentState().error); this.errorHandlerService.processError(error); } @@ -380,17 +397,17 @@ export abstract class DataJobsBaseGridComponent this._initializeClrGridUIState(); this.subscriptions.push( - this.loadDataDebouncer.pipe( - debounceTime(300) - ).subscribe((handling) => { - if (this.isLoadDataAllowed() || handling === 'forced') { - this._doLoadData(); - } + this.loadDataDebouncer + .pipe(debounceTime(300)) + .subscribe((handling) => { + if (this.isLoadDataAllowed() || handling === 'forced') { + this._doLoadData(); + } - if (this.isUrlUpdateAllowed() || handling === 'forced') { - this._doUrlUpdate(); - } - }) + if (this.isUrlUpdateAllowed() || handling === 'forced') { + this._doUrlUpdate(); + } + }) ); super.ngOnInit(); @@ -400,12 +417,19 @@ export abstract class DataJobsBaseGridComponent try { this._loadLocalStorageUserConfig(); } catch (e1) { - console.error('Failed to read config from localStorage', e1, 'Will attempt to re-create it.'); + console.error( + 'Failed to read config from localStorage', + e1, + 'Will attempt to re-create it.' + ); try { localStorage.removeItem(this.localStorageConfigKey); this._loadLocalStorageUserConfig(); } catch (e2) { - console.error('Was unable to re-initialize localStorage user config', e2); + console.error( + 'Was unable to re-initialize localStorage user config', + e2 + ); } } } @@ -413,7 +437,9 @@ export abstract class DataJobsBaseGridComponent protected isLoadDataAllowed(): boolean { if (!this.gridState) { //While the gridState is empty, no refresh requests will be executed. - console.log('Load data will be skipped. gridState is empty. operation not allowed.'); + console.log( + 'Load data will be skipped. gridState is empty. operation not allowed.' + ); return false; } @@ -422,34 +448,50 @@ export abstract class DataJobsBaseGridComponent } protected isUrlUpdateAllowed(): boolean { - return !this.navigationInProgress && this.urlStateManager.isQueryParamsStateMutated; + return ( + !this.navigationInProgress && + this.urlStateManager.isQueryParamsStateMutated + ); } protected saveUIState() { - const dataGrid = this.elementRef.nativeElement.querySelector(DataJobsBaseGridComponent.DATA_GRID_SELECTOR); + const dataGrid = this.elementRef.nativeElement.querySelector( + DataJobsBaseGridComponent.DATA_GRID_SELECTOR + ); if (dataGrid) { - this.model.withUiState(DataJobsBaseGridComponent.UI_KEY_GRID_OFFSET, { - x: dataGrid.scrollLeft, - y: dataGrid.scrollTop - }); + this.model.withUiState( + DataJobsBaseGridComponent.UI_KEY_GRID_OFFSET, + { + x: dataGrid.scrollLeft, + y: dataGrid.scrollTop, + } + ); } - const contentArea = this.document.querySelector(DataJobsBaseGridComponent.CONTENT_AREA_SELECTOR); + const contentArea = this.document.querySelector( + DataJobsBaseGridComponent.CONTENT_AREA_SELECTOR + ); if (contentArea) { - this.model.withUiState(DataJobsBaseGridComponent.UI_KEY_PAGE_OFFSET, { - x: contentArea.scrollLeft, - y: contentArea.scrollTop - }); + this.model.withUiState( + DataJobsBaseGridComponent.UI_KEY_PAGE_OFFSET, + { + x: contentArea.scrollLeft, + y: contentArea.scrollTop, + } + ); } - const clrGridUIStateDeepCloned = CollectionsUtil.cloneDeep(this.clrGridUIState); - clrGridUIStateDeepCloned.pageSize = this.model - .getComponentState() - ?.page - ?.size; + const clrGridUIStateDeepCloned = CollectionsUtil.cloneDeep( + this.clrGridUIState + ); + clrGridUIStateDeepCloned.pageSize = + this.model.getComponentState()?.page?.size; clrGridUIStateDeepCloned.lastPage = this.clrGridCurrentPage; - this.model.withUiState(DataJobsBaseGridComponent.UI_KEY_GRID_UI_STATE, clrGridUIStateDeepCloned); + this.model.withUiState( + DataJobsBaseGridComponent.UI_KEY_GRID_UI_STATE, + clrGridUIStateDeepCloned + ); this.componentService.update(this.model.getComponentState()); } @@ -460,14 +502,22 @@ export abstract class DataJobsBaseGridComponent } setTimeout(() => { - const gridOffset = this.model.getUiState(DataJobsBaseGridComponent.UI_KEY_GRID_OFFSET); - const dataGrid = this.elementRef.nativeElement.querySelector(DataJobsBaseGridComponent.DATA_GRID_SELECTOR); + const gridOffset = this.model.getUiState( + DataJobsBaseGridComponent.UI_KEY_GRID_OFFSET + ); + const dataGrid = this.elementRef.nativeElement.querySelector( + DataJobsBaseGridComponent.DATA_GRID_SELECTOR + ); if (dataGrid) { dataGrid.scrollTo(gridOffset.x, gridOffset.y); } - const pageOffset = this.model.getUiState(DataJobsBaseGridComponent.UI_KEY_PAGE_OFFSET); - const contentArea = this.document.querySelector(DataJobsBaseGridComponent.CONTENT_AREA_SELECTOR); + const pageOffset = this.model.getUiState( + DataJobsBaseGridComponent.UI_KEY_PAGE_OFFSET + ); + const contentArea = this.document.querySelector( + DataJobsBaseGridComponent.CONTENT_AREA_SELECTOR + ); if (contentArea) { contentArea.scrollTo(pageOffset.x, pageOffset.y); } @@ -477,7 +527,8 @@ export abstract class DataJobsBaseGridComponent } private _shouldRestoreUIState(routerState: RouterState): boolean { - const restoreUiWhen = routerState.state.getData('restoreUiWhen'); + const restoreUiWhen = + routerState.state.getData('restoreUiWhen'); if (CollectionsUtil.isNil(restoreUiWhen)) { return true; } @@ -488,34 +539,34 @@ export abstract class DataJobsBaseGridComponent return routerState .getPrevious() - .state - .absoluteConfigPath - .includes(restoreUiWhen.previousConfigPathLike); + .state.absoluteConfigPath.includes( + restoreUiWhen.previousConfigPathLike + ); } private _doesRestoreUIStateExist(): boolean { - return CollectionsUtil.isDefined(this.model) - && CollectionsUtil.isDefined( - this.model.getUiState(DataJobsBaseGridComponent.UI_KEY_GRID_UI_STATE) - ); + return ( + CollectionsUtil.isDefined(this.model) && + CollectionsUtil.isDefined( + this.model.getUiState( + DataJobsBaseGridComponent.UI_KEY_GRID_UI_STATE + ) + ) + ); } private _clearUiPageState() { this.model .getComponentState() - .uiState - .delete(DataJobsBaseGridComponent.UI_KEY_GRID_OFFSET); + .uiState.delete(DataJobsBaseGridComponent.UI_KEY_GRID_OFFSET); this.model .getComponentState() - .uiState - .delete(DataJobsBaseGridComponent.UI_KEY_PAGE_OFFSET); + .uiState.delete(DataJobsBaseGridComponent.UI_KEY_PAGE_OFFSET); this.model .getComponentState() - .uiState - .delete(DataJobsBaseGridComponent.UI_KEY_GRID_UI_STATE); + .uiState.delete(DataJobsBaseGridComponent.UI_KEY_GRID_UI_STATE); - this.componentService - .update(this.model.getComponentState()); + this.componentService.update(this.model.getComponentState()); } private _doLoadData(): void { @@ -528,7 +579,10 @@ export abstract class DataJobsBaseGridComponent this.model .withFilter(this._buildRefreshFilters()) .withSearch(this.searchQueryValue) - .withPage(this.gridState?.page?.current, this.gridState?.page?.size); + .withPage( + this.gridState?.page?.current, + this.gridState?.page?.size + ); } this.dataJobsService.loadJobs(this.model); @@ -560,8 +614,10 @@ export abstract class DataJobsBaseGridComponent this.urlStateManager.baseURL = routeState.absoluteRoutePath; } - this.urlStateManager - .setQueryParam(this.searchParam, this.searchQueryValue); + this.urlStateManager.setQueryParam( + this.searchParam, + this.searchQueryValue + ); } private _doUrlUpdate(): void { @@ -569,9 +625,7 @@ export abstract class DataJobsBaseGridComponent this.urlStateManager.locationToURL(); } else { // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.urlStateManager - .navigateToUrl() - .then(); + this.urlStateManager.navigateToUrl().then(); } } @@ -579,22 +633,32 @@ export abstract class DataJobsBaseGridComponent const userConfig = localStorage.getItem(this.localStorageConfigKey); if (userConfig) { let newColumnProvided = false; - const parsedUserConfig: DataJobsLocalStorageUserConfig = JSON.parse(userConfig); - - CollectionsUtil.iterateObject(this.localStorageUserConfig.hiddenColumns, (value, key) => { - if (!parsedUserConfig.hiddenColumns.hasOwnProperty(key)) { - newColumnProvided = true; - parsedUserConfig.hiddenColumns[key] = value; + const parsedUserConfig: DataJobsLocalStorageUserConfig = + JSON.parse(userConfig); + + CollectionsUtil.iterateObject( + this.localStorageUserConfig.hiddenColumns, + (value, key) => { + if (!parsedUserConfig.hiddenColumns.hasOwnProperty(key)) { + newColumnProvided = true; + parsedUserConfig.hiddenColumns[key] = value; + } } - }); + ); if (newColumnProvided) { - localStorage.setItem(this.localStorageConfigKey, JSON.stringify(parsedUserConfig)); + localStorage.setItem( + this.localStorageConfigKey, + JSON.stringify(parsedUserConfig) + ); } this.localStorageUserConfig = parsedUserConfig; } else { - localStorage.setItem(this.localStorageConfigKey, JSON.stringify(this.localStorageUserConfig)); + localStorage.setItem( + this.localStorageConfigKey, + JSON.stringify(this.localStorageUserConfig) + ); } } @@ -610,31 +674,32 @@ export abstract class DataJobsBaseGridComponent filters.push({ property: 'config.team', pattern: this.teamNameFilter, - sort: null + sort: null, }); } if (this.gridState?.filters) { for (const _filter of this.gridState.filters) { - const { property, value } = _filter as { property: string; value: string }; + const { property, value } = _filter as { + property: string; + value: string; + }; filters.push({ property, pattern: this._getFilterPattern(property, value), - sort: null + sort: null, }); } } if (this.gridState?.sort) { - const direction = this.gridState.sort.reverse - ? DESC - : ASC; + const direction = this.gridState.sort.reverse ? DESC : ASC; filters.push({ property: this.gridState.sort.by as string, pattern: null, - sort: direction + sort: direction, }); } @@ -646,13 +711,13 @@ export abstract class DataJobsBaseGridComponent // TODO: Once jobName get the same handling as config.team, add case proper case switch (propertyName) { case 'config.team': - return `%${ value }%`; + return `%${value}%`; case 'deployments.enabled': - return `${ value }`.toLowerCase().replace(' ', '_'); + return `${value}`.toLowerCase().replace(' ', '_'); case 'deployments.lastExecutionStatus': - return `${ value }`.toLowerCase(); + return `${value}`.toLowerCase(); default: - return `${ value }`; + return `${value}`; } } @@ -671,7 +736,7 @@ export abstract class DataJobsBaseGridComponent suppressCancel: true, onActivate: () => { this.clrGridUIState.filter = {}; - } + }, }, { label: 'Enabled', @@ -681,8 +746,8 @@ export abstract class DataJobsBaseGridComponent title: 'Enabled - This job is deployed and executed by schedule', class: 'is-solid status-icon-enabled', shape: 'check-circle', - size: 20 - } + size: 20, + }, }, { label: 'Disabled', @@ -692,8 +757,8 @@ export abstract class DataJobsBaseGridComponent title: 'Disabled - This job is deployed but not executing by schedule', class: 'is-solid status-icon-disabled', shape: 'times-circle', - size: 15 - } + size: 15, + }, }, { label: 'Not Deployed', @@ -702,14 +767,17 @@ export abstract class DataJobsBaseGridComponent icon: { title: 'Not Deployed - This job is created but still not deployed', shape: 'circle', - size: 15 - } - } + size: 15, + }, + }, ]; - if (CollectionsUtil.isNumber(this.quickFiltersDefaultActiveIndex) && - CollectionsUtil.isDefined(filters[this.quickFiltersDefaultActiveIndex])) { - + if ( + CollectionsUtil.isNumber(this.quickFiltersDefaultActiveIndex) && + CollectionsUtil.isDefined( + filters[this.quickFiltersDefaultActiveIndex] + ) + ) { filters[this.quickFiltersDefaultActiveIndex].active = true; } @@ -722,11 +790,11 @@ export abstract class DataJobsBaseGridComponent lastPage: 1, pageSize: 25, filter: { - ...(this.clrGridDefaultFilter ?? {}) + ...(this.clrGridDefaultFilter ?? {}), }, sort: { - ...(this.clrGridDefaultSort ?? {}) - } + ...(this.clrGridDefaultSort ?? {}), + }, }; } } diff --git a/projects/frontend/data-pipelines/gui/projects/data-pipelines/src/lib/components/data-job/data-job-page.component.html b/projects/frontend/data-pipelines/gui/projects/data-pipelines/src/lib/components/data-job/data-job-page.component.html index 4a998972e0..41269c4327 100644 --- a/projects/frontend/data-pipelines/gui/projects/data-pipelines/src/lib/components/data-job/data-job-page.component.html +++ b/projects/frontend/data-pipelines/gui/projects/data-pipelines/src/lib/components/data-job/data-job-page.component.html @@ -5,161 +5,227 @@ -
-
- +
+
-
-

- - +
+

+ + - Data Job: {{jobName}} + Data Job: {{ jobName }}

-

- - +

+ + - Data Job: {{jobName}} + Data Job: {{ jobName }}

-
- - - - - - - -
- + - + - +
-