From 4b2fdda20fb43f905994c7526d5581d58bfc9a85 Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
<66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Mon, 8 Dec 2025 19:17:36 +0000
Subject: [PATCH 1/2] [pre-commit.ci] pre-commit autoupdate
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
updates:
- [github.com/pre-commit/pre-commit-hooks: v4.5.0 → v6.0.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.5.0...v6.0.0)
- https://github.com/psf/black → https://github.com/psf/black-pre-commit-mirror
- [github.com/psf/black-pre-commit-mirror: 23.11.0 → 25.12.0](https://github.com/psf/black-pre-commit-mirror/compare/23.11.0...25.12.0)
- [github.com/asottile/reorder-python-imports: v3.12.0 → v3.16.0](https://github.com/asottile/reorder-python-imports/compare/v3.12.0...v3.16.0)
- [github.com/asottile/pyupgrade: v3.15.0 → v3.21.2](https://github.com/asottile/pyupgrade/compare/v3.15.0...v3.21.2)
- [github.com/Lucas-C/pre-commit-hooks: v1.5.4 → v1.5.5](https://github.com/Lucas-C/pre-commit-hooks/compare/v1.5.4...v1.5.5)
- [github.com/pre-commit/mirrors-prettier: v3.1.0 → v4.0.0-alpha.8](https://github.com/pre-commit/mirrors-prettier/compare/v3.1.0...v4.0.0-alpha.8)
---
.pre-commit-config.yaml | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 47fed3a154..dafe2ae844 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -3,7 +3,7 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.5.0
+ rev: v6.0.0
hooks:
- id: check-yaml
args: [ '--unsafe' ]
@@ -21,8 +21,8 @@ repos:
- id: requirements-txt-fixer
- id: detect-private-key
- id: fix-byte-order-marker
- - repo: https://github.com/psf/black
- rev: 23.11.0
+ - repo: https://github.com/psf/black-pre-commit-mirror
+ rev: 25.12.0
hooks:
- id: black
language_version: python3
@@ -46,13 +46,13 @@ repos:
# - id: mypy
# files: ^(src/|tests/|plugins/)
- repo: https://github.com/asottile/reorder-python-imports
- rev: v3.12.0
+ rev: v3.16.0
hooks:
- id: reorder-python-imports
args: [ --py37-plus, '--application-directories=.:src' ]
# use latest python syntax
- repo: https://github.com/asottile/pyupgrade
- rev: v3.15.0
+ rev: v3.21.2
hooks:
- id: pyupgrade
args: [ --py37-plus ]
@@ -65,7 +65,7 @@ repos:
# args: [ -s, B101 ]
# add copyright notice
- repo: https://github.com/Lucas-C/pre-commit-hooks
- rev: v1.5.4
+ rev: v1.5.5
hooks:
- id: insert-license
files: \.java$
@@ -144,7 +144,7 @@ repos:
- --license-filepath
- NOTICE.txt
- repo: https://github.com/pre-commit/mirrors-prettier
- rev: v3.1.0
+ rev: v4.0.0-alpha.8
hooks:
- id: prettier
types_or: [scss, css, javascript, ts, html]
From c264075666db897e2314a9c0f62ba7c3b62b523d Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
<66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Mon, 8 Dec 2025 19:18:17 +0000
Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
---
.../pgvector-embedder/40_ingest_embeddings.py | 8 +-
.../explore/data-jobs/data-jobs.spec.js | 720 +-
.../details/data-job-details.spec.js | 257 +-
.../executions/data-job-executions.spec.js | 150 +-
...ted-page-data-jobs-health-overview.spec.js | 237 +-
.../get-started/get-started-page.spec.js | 60 +-
.../manage/data-jobs/data-jobs.spec.js | 988 +-
.../details/data-job-details.spec.js | 479 +-
.../executions/data-job-executions.spec.js | 3442 ++-
.../frontend-tests/router/router.spec.js | 30 +-
.../quickstart-operability/quickstart.spec.js | 50 +-
.../helpers/authentication-helpers.plugins.js | 20 +-
.../plugins/helpers/http-helpers.plugins.js | 351 +-
.../plugins/helpers/job-helpers.plugins.js | 1489 +-
.../plugins/helpers/logger-helpers.plugins.js | 24 +-
.../plugins/helpers/util-helpers.plugins.js | 279 +-
.../data-pipelines/gui/e2e/plugins/index.js | 315 +-
.../gui/e2e/support/commands.js | 412 +-
.../e2e/support/helpers/constants.support.js | 113 +-
.../data-pipelines/gui/e2e/support/index.js | 40 +-
.../e2e/support/pages/base/base-page.po.js | 1340 +-
.../base/data-pipelines/data-job-base.po.js | 817 +-
.../data-job-details-base.po.js | 152 +-
.../base/data-pipelines/data-jobs-base.po.js | 601 +-
.../data-pipelines/data-pipelines-base.po.js | 961 +-
.../pages/explore/data-jobs/data-jobs.po.js | 124 +-
.../data-jobs/details/data-job-details.po.js | 36 +-
.../executions/data-job-executions.po.js | 36 +-
...arted-page-data-jobs-health-overview.po.js | 388 +-
.../pages/get-started/get-started-page.po.js | 72 +-
.../pages/manage/data-jobs/data-jobs.po.js | 301 +-
.../data-jobs/details/data-job-details.po.js | 495 +-
.../executions/data-job-executions.po.js | 1366 +-
.../gui/projects/data-pipelines/karma.conf.js | 113 +-
.../filters-sort-manager.spec.ts | 3847 +--
.../filters-manager/filters-sort-manager.ts | 1072 +-
.../src/lib/commons/filters-manager/index.ts | 2 +-
.../data-pipelines/src/lib/commons/index.ts | 2 +-
.../_data-jobs-base-grid.component.scss | 196 +-
.../data-jobs-base-grid.component.ts | 1759 +-
.../data-job/data-job-page.component.html | 412 +-
.../data-job/data-job-page.component.scss | 138 +-
.../data-job/data-job-page.component.spec.ts | 560 +-
.../data-job/data-job-page.component.ts | 1275 +-
.../src/lib/components/data-job/index.ts | 2 +-
.../data-job-details-page.component.html | 1548 +-
.../data-job-details-page.component.scss | 158 +-
.../data-job-details-page.component.spec.ts | 628 +-
.../data-job-details-page.component.ts | 1204 +-
.../data-job/pages/details/index.ts | 2 +-
.../data-job/pages/details/public-api.ts | 2 +-
...ob-deployment-details-modal.component.html | 165 +-
...ob-deployment-details-modal.component.scss | 12 +-
...-job-deployment-details-modal.component.ts | 32 +-
.../index.ts | 2 +-
...job-execution-status-filter.component.html | 38 +-
...a-job-execution-status-filter.component.ts | 197 +-
.../data-job-execution-status-filter/index.ts | 2 +-
.../data-job-execution-status.component.html | 70 +-
.../data-job-execution-status.component.scss | 34 +-
.../data-job-execution-status.component.ts | 162 +-
.../data-job-execution-status/index.ts | 2 +-
...a-job-execution-type-filter.component.html | 32 +-
...ata-job-execution-type-filter.component.ts | 179 +-
.../data-job-execution-type-filter/index.ts | 2 +-
.../data-job-execution-type.component.html | 20 +-
.../data-job-execution-type.component.ts | 32 +-
.../data-job-execution-type/index.ts | 2 +-
.../date/execution-date.comparator.spec.ts | 192 +-
.../date/execution-date.comparator.ts | 72 +-
.../comparators/date/index.ts | 2 +-
.../execution-default.comparator.spec.ts | 274 +-
.../default/execution-default.comparator.ts | 68 +-
.../comparators/default/index.ts | 2 +-
.../execution-duration.comparator.spec.ts | 172 +-
.../duration/execution-duration.comparator.ts | 36 +-
.../comparators/duration/index.ts | 2 +-
.../comparators/index.ts | 6 +-
.../criteria/index.ts | 6 +-
.../status/executions-status.criteria.spec.ts | 303 +-
.../status/executions-status.criteria.ts | 75 +-
.../criteria/status/index.ts | 2 +-
.../string/executions-string.criteria.spec.ts | 286 +-
.../string/executions-string.criteria.ts | 79 +-
.../criteria/string/index.ts | 2 +-
.../type/executions-type.criteria.spec.ts | 308 +-
.../criteria/type/executions-type.criteria.ts | 75 +-
.../criteria/type/index.ts | 2 +-
.../data-job-executions-grid.component.html | 316 +-
.../data-job-executions-grid.component.scss | 38 +-
.../data-job-executions-grid.component.ts | 868 +-
.../data-job-executions-grid/index.ts | 4 +-
.../executions-time-period.criteria.spec.ts | 298 +-
.../executions-time-period.criteria.ts | 68 +-
.../criteria/time-period/index.ts | 2 +-
.../data-job-executions-page.component.html | 142 +-
.../data-job-executions-page.component.scss | 42 +-
.../data-job-executions-page.component.ts | 824 +-
.../data-job-executions-page/index.ts | 2 +-
.../execution-duration-chart.component.html | 32 +-
.../execution-duration-chart.component.scss | 26 +-
.../execution-duration-chart.component.ts | 858 +-
.../execution-duration-chart/index.ts | 2 +-
.../execution-status-chart.component.html | 18 +-
.../execution-status-chart.component.scss | 22 +-
.../execution-status-chart.component.ts | 211 +-
.../execution-status-chart/index.ts | 2 +-
.../data-job/pages/executions/index.ts | 22 +-
.../model/data-job-execution.spec.ts | 360 +-
.../executions/model/data-job-execution.ts | 149 +-
.../model/executions-filters.model.spec.ts | 90 +-
.../model/executions-filters.model.ts | 101 +-
.../data-job/pages/executions/model/index.ts | 4 +-
.../data-job/pages/executions/public-api.ts | 2 +-
.../executions/time-period-filter/index.ts | 2 +-
.../time-period-filter.component.html | 295 +-
.../time-period-filter.component.scss | 624 +-
.../time-period-filter.component.ts | 1139 +-
.../src/lib/components/data-job/public-api.ts | 6 +-
.../data-jobs-explore-grid.component.html | 976 +-
.../data-jobs-explore-grid.component.scss | 8 +-
.../data-jobs-explore-grid.component.spec.ts | 736 +-
.../grid/data-jobs-explore-grid.component.ts | 165 +-
.../components/grid/index.ts | 2 +-
.../data-jobs-explore-page.component.css | 6 +-
.../data-jobs-explore-page.component.html | 12 +-
.../data-jobs-explore-page.component.spec.ts | 32 +-
.../data-jobs-explore-page.component.ts | 8 +-
.../lib/components/data-jobs-explore/index.ts | 2 +-
.../data-jobs-explore/public-api.ts | 4 +-
.../grid/data-jobs-manage-grid.component.html | 1127 +-
.../grid/data-jobs-manage-grid.component.scss | 12 +-
.../data-jobs-manage-grid.component.spec.ts | 809 +-
.../grid/data-jobs-manage-grid.component.ts | 436 +-
.../data-jobs-manage/components/grid/index.ts | 2 +-
.../data-jobs-manage-page.component.css | 6 +-
.../data-jobs-manage-page.component.html | 12 +-
.../data-jobs-manage-page.component.spec.ts | 32 +-
.../data-jobs-manage-page.component.ts | 8 +-
.../lib/components/data-jobs-manage/index.ts | 2 +-
.../components/data-jobs-manage/public-api.ts | 4 +-
.../src/lib/components/public-api.ts | 8 +-
...data-jobs-executions-widget.component.html | 106 +-
...data-jobs-executions-widget.component.scss | 84 +-
.../data-jobs-executions-widget.component.ts | 85 +-
.../data-jobs-executions-widget/index.ts | 2 +-
.../data-jobs-failed-widget.component.html | 72 +-
.../data-jobs-failed-widget.component.scss | 74 +-
.../data-jobs-failed-widget.component.ts | 110 +-
.../widgets/data-jobs-failed-widget/index.ts | 2 +-
.../data-jobs-health-panel.component.html | 129 +-
.../data-jobs-health-panel.component.scss | 466 +-
.../data-jobs-health-panel.component.ts | 467 +-
.../widgets/data-jobs-health-panel/index.ts | 2 +-
.../data-jobs-widget-one.component.html | 389 +-
.../data-jobs-widget-one.component.scss | 444 +-
.../data-jobs-widget-one.component.spec.ts | 202 +-
.../widgets/data-jobs-widget-one.component.ts | 342 +-
.../src/lib/components/widgets/index.ts | 10 +-
.../src/lib/components/widgets/public-api.ts | 2 +-
.../widget-execution-status-gauge/index.ts | 2 +-
...dget-execution-status-gauge.component.html | 110 +-
...dget-execution-status-gauge.component.scss | 760 +-
...widget-execution-status-gauge.component.ts | 65 +-
.../src/lib/components/widgets/widget.scss | 28 +-
.../src/lib/model/config.model.ts | 211 +-
.../src/lib/model/constants.model.ts | 34 +-
.../src/lib/model/data-job-base.model.ts | 114 +-
.../lib/model/data-job-deployments.model.ts | 19 +-
.../src/lib/model/data-job-details.model.ts | 78 +-
.../lib/model/data-job-executions.model.ts | 52 +-
.../src/lib/model/data-job.model.ts | 48 +-
.../src/lib/model/grid-config.model.ts | 20 +-
.../data-pipelines/src/lib/model/index.ts | 20 +-
.../src/lib/model/public-api.ts | 24 +-
.../src/lib/model/route.model.ts | 113 +-
.../src/lib/model/toast-definitions.model.ts | 16 +-
.../data-jobs-base.api.service.spec.ts | 485 +-
.../services/data-jobs-base.api.service.ts | 250 +-
.../data-jobs-public.api.service.spec.ts | 376 +-
.../services/data-jobs-public.api.service.ts | 295 +-
.../services/data-jobs.api.service.spec.ts | 665 +-
.../src/lib/services/data-jobs.api.service.ts | 483 +-
.../lib/services/data-jobs.service.spec.ts | 423 +-
.../src/lib/services/data-jobs.service.ts | 298 +-
.../data-pipelines/src/lib/services/index.ts | 8 +-
.../src/lib/services/public-api.ts | 2 +-
.../confirmation-dialog-modal.component.html | 76 +-
.../confirmation-dialog-modal.component.scss | 20 +-
...onfirmation-dialog-modal.component.spec.ts | 48 +-
.../confirmation-dialog-modal.component.ts | 32 +-
.../confirmation-dialog-modal/index.ts | 2 +-
.../column-filter.component.html | 45 +-
.../column-filter.component.scss | 10 +-
.../column-filter.component.spec.ts | 94 +-
.../column-filter/column-filter.component.ts | 133 +-
.../data-grid/column-filter/index.ts | 2 +-
.../grid-action/grid-action.component.html | 160 +-
.../grid-action/grid-action.component.scss | 114 +-
.../grid-action/grid-action.component.spec.ts | 60 +-
.../grid-action/grid-action.component.ts | 195 +-
.../components/data-grid/grid-action/index.ts | 2 +-
.../lib/shared/components/data-grid/index.ts | 4 +-
.../delete-modal/delete-modal.component.html | 74 +-
.../delete-modal.component.spec.ts | 56 +-
.../delete-modal/delete-modal.component.ts | 38 +-
.../shared/components/delete-modal/index.ts | 2 +-
.../empty-state/empty-state.component.html | 42 +-
.../empty-state/empty-state.component.scss | 26 +-
.../empty-state/empty-state.component.spec.ts | 36 +-
.../empty-state/empty-state.component.ts | 26 +-
.../shared/components/empty-state/index.ts | 2 +-
.../executions-timeline.component.html | 341 +-
.../executions-timeline.component.scss | 72 +-
.../executions-timeline.component.spec.ts | 120 +-
.../executions-timeline.component.ts | 128 +-
.../components/executions-timeline/index.ts | 2 +-
.../src/lib/shared/components/index.ts | 18 +-
.../src/lib/shared/components/modal/index.ts | 2 +-
.../components/modal/modal.component.ts | 56 +-
.../shared/components/quick-filters/index.ts | 4 +-
.../components/quick-filters/model/index.ts | 2 +-
.../model/quick-filters.model.ts | 34 +-
.../quick-filters.component.html | 57 +-
.../quick-filters.component.scss | 56 +-
.../quick-filters.component.spec.ts | 36 +-
.../quick-filters/quick-filters.component.ts | 226 +-
.../src/lib/shared/components/status/index.ts | 4 +-
.../status-cell/status-cell.component.css | 4 +-
.../status-cell/status-cell.component.html | 66 +-
.../status-cell/status-cell.component.spec.ts | 48 +-
.../status-cell/status-cell.component.ts | 12 +-
.../status-panel/status-panel.component.html | 46 +-
.../status-panel.component.spec.ts | 38 +-
.../status-panel/status-panel.component.ts | 12 +-
.../shared/components/widget-value/index.ts | 2 +-
.../widget-value/widget-value.component.html | 38 +-
.../widget-value.component.spec.ts | 36 +-
.../widget-value/widget-value.component.ts | 16 +-
.../directives/attribute.directive.spec.ts | 311 +-
.../shared/directives/attribute.directive.ts | 197 +-
.../src/lib/shared/directives/index.ts | 2 +-
.../src/lib/shared/model/index.ts | 2 +-
.../lib/shared/model/modal-options.spec.ts | 74 +-
.../src/lib/shared/model/modal-options.ts | 128 +-
.../pipes/contacts-present.pipe.spec.ts | 188 +-
.../lib/shared/pipes/contacts-present.pipe.ts | 44 +-
.../pipes/execution-success-rate.pipe.spec.ts | 158 +-
.../pipes/execution-success-rate.pipe.ts | 70 +-
.../lib/shared/pipes/extract-contacts.pipe.ts | 22 +-
.../pipes/extract-job-status.pipe.spec.ts | 92 +-
.../shared/pipes/extract-job-status.pipe.ts | 56 +-
.../shared/pipes/format-delta.pipe.spec.ts | 164 +-
.../src/lib/shared/pipes/format-delta.pipe.ts | 93 +-
.../lib/shared/pipes/format-duration.pipe.ts | 20 +-
.../shared/pipes/format-schedule.pipe.spec.ts | 808 +-
.../lib/shared/pipes/format-schedule.pipe.ts | 108 +-
.../src/lib/shared/pipes/index.ts | 16 +-
.../lib/shared/pipes/parse-epoch.pipe.spec.ts | 42 +-
.../src/lib/shared/pipes/parse-epoch.pipe.ts | 46 +-
.../shared/pipes/parse-next-run.pipe.spec.ts | 350 +-
.../lib/shared/pipes/parse-next-run.pipe.ts | 48 +-
.../src/lib/shared/utils/cron.util.spec.ts | 24 +-
.../src/lib/shared/utils/cron.util.ts | 24 +-
.../lib/shared/utils/data-job.util.spec.ts | 500 +-
.../src/lib/shared/utils/data-job.util.ts | 165 +-
.../src/lib/shared/utils/date.util.spec.ts | 91 +-
.../src/lib/shared/utils/date.util.ts | 23 +-
.../src/lib/shared/utils/error.util.ts | 25 +-
.../src/lib/shared/utils/index.ts | 10 +-
.../src/lib/shared/utils/string.util.spec.ts | 34 +-
.../src/lib/shared/utils/string.util.ts | 3 +-
.../lib/state/actions/data-jobs.actions.ts | 9 +-
.../src/lib/state/actions/index.ts | 2 +-
.../state/effects/data-jobs.effects.spec.ts | 1125 +-
.../lib/state/effects/data-jobs.effects.ts | 847 +-
.../src/lib/state/effects/index.ts | 2 +-
.../state/error-codes/data-job.error-codes.ts | 48 +-
.../src/lib/state/error-codes/index.ts | 2 +-
.../src/lib/state/tasks/data-job.tasks.ts | 21 +-
.../src/lib/state/tasks/index.ts | 2 +-
.../src/lib/vdk-data-pipelines.module.ts | 298 +-
.../projects/data-pipelines/src/public-api.ts | 8 +-
.../gui/projects/data-pipelines/src/test.ts | 39 +-
.../gui/projects/ui/karma.conf.js | 111 +-
.../projects/ui/src/app/app-config.model.ts | 34 +-
.../ui/src/app/app-config.service.spec.ts | 36 +-
.../projects/ui/src/app/app-config.service.ts | 110 +-
.../projects/ui/src/app/app.component.html | 198 +-
.../projects/ui/src/app/app.component.scss | 64 +-
.../projects/ui/src/app/app.component.spec.ts | 261 +-
.../gui/projects/ui/src/app/app.component.ts | 248 +-
.../gui/projects/ui/src/app/app.module.ts | 180 +-
.../gui/projects/ui/src/app/app.routing.ts | 202 +-
.../getting-started.component.html | 182 +-
.../getting-started.component.spec.ts | 92 +-
.../getting-started.component.ts | 24 +-
.../projects/ui/src/app/http.interceptor.ts | 119 +-
.../projects/ui/src/assets/css/clr-ui.min.css | 25201 ++++++++--------
.../ui/src/environments/environment.prod.ts | 2 +-
.../ui/src/environments/environment.ts | 4 +-
.../gui/projects/ui/src/index.html | 46 +-
.../gui/projects/ui/src/main.ts | 14 +-
.../gui/projects/ui/src/polyfills.ts | 4 +-
.../gui/projects/ui/src/styles.scss | 202 +-
.../gui/projects/ui/src/test.ts | 37 +-
.../projects/documentation-ui/karma.conf.js | 113 +-
.../src/app/app-routing.module.ts | 30 +-
.../src/app/app.component.html | 108 +-
.../src/app/app.component.scss | 44 +-
.../src/app/app.component.spec.ts | 46 +-
.../documentation-ui/src/app/app.component.ts | 56 +-
.../documentation-ui/src/app/app.module.ts | 109 +-
.../projects/documentation-ui/src/app/auth.ts | 36 +-
.../src/app/core/core.component.html | 6 +-
.../src/app/core/core.component.scss | 20 +-
.../src/app/core/core.component.spec.ts | 40 +-
.../src/app/core/core.component.ts | 8 +-
.../src/app/core/core.module.ts | 22 +-
.../src/app/http.interceptor.ts | 103 +-
.../src/environments/environment.prod.ts | 2 +-
.../src/environments/environment.ts | 4 +-
.../projects/documentation-ui/src/index.html | 26 +-
.../gui/projects/documentation-ui/src/main.ts | 14 +-
.../documentation-ui/src/polyfills.ts | 4 +-
.../projects/documentation-ui/src/styles.scss | 218 +-
.../gui/projects/documentation-ui/src/test.ts | 37 +-
.../gui/projects/shared/karma.conf.js | 110 +-
.../common/criteria/compound/and.criteria.ts | 48 +-
.../src/lib/common/criteria/compound/index.ts | 4 +-
.../common/criteria/compound/or.criteria.ts | 50 +-
.../shared/src/lib/common/criteria/index.ts | 4 +-
.../lib/common/criteria/primitive/index.ts | 2 +-
.../criteria/primitive/primitive.criteria.ts | 40 +-
.../src/lib/common/criteria/public-api.ts | 4 +-
.../model/interfaces/api-error.interface.ts | 18 +-
.../error/api-error/model/interfaces/index.ts | 2 +-
.../shared/src/lib/common/error/index.ts | 8 +-
.../shared/src/lib/common/error/public-api.ts | 2 +-
.../model/interfaces/error-store.interface.ts | 276 +-
.../error/store/model/interfaces/index.ts | 2 +-
.../error/ui-error/model/interfaces/index.ts | 2 +-
.../model/interfaces/ui-error.interface.ts | 244 +-
.../error/utils/error-store.utils.spec.ts | 84 +-
.../common/error/utils/error-store.utils.ts | 145 +-
.../src/lib/common/error/utils/index.ts | 2 +-
.../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 | 721 +-
.../lib/common/http/request/request.model.ts | 279 +-
.../projects/shared/src/lib/common/index.ts | 18 +-
.../common/interfaces/comparable.interface.ts | 96 +-
.../common/interfaces/comparator.interface.ts | 8 +-
.../lib/common/interfaces/copy.interface.ts | 10 +-
.../common/interfaces/criteria.interface.ts | 12 +-
.../lib/common/interfaces/equals.interface.ts | 8 +-
.../common/interfaces/expression.interface.ts | 20 +-
.../shared/src/lib/common/interfaces/index.ts | 20 +-
.../common/interfaces/literal.interface.ts | 34 +-
.../common/interfaces/predicate.interface.ts | 23 +-
.../src/lib/common/interfaces/public-api.ts | 2 +-
.../common/interfaces/replacer.interface.ts | 4 +-
.../interfaces/serializable.interface.ts | 20 +-
.../shared/src/lib/common/object/index.ts | 2 +-
.../src/lib/common/object/model/index.ts | 2 +-
.../object/model/taurus-object.model.spec.ts | 305 +-
.../object/model/taurus-object.model.ts | 204 +-
.../src/lib/common/object/public-api.ts | 2 +-
.../comparable/comparable.impl.spec.ts | 498 +-
.../predicate/comparable/comparable.impl.ts | 191 +-
.../lib/common/predicate/comparable/index.ts | 4 +-
.../predicates-comparable.impl.spec.ts | 599 +-
.../comparable/predicates-comparable.impl.ts | 206 +-
.../predicate/compound/and.predicate.spec.ts | 260 +-
.../predicate/compound/and.predicate.ts | 40 +-
.../compound/base-compound.predicate.spec.ts | 42 +-
.../compound/base-compound.predicate.ts | 67 +-
.../lib/common/predicate/compound/index.ts | 6 +-
.../predicate/compound/or.predicate.spec.ts | 260 +-
.../common/predicate/compound/or.predicate.ts | 40 +-
.../shared/src/lib/common/predicate/index.ts | 6 +-
.../src/lib/common/predicate/public-api.ts | 2 +-
.../simple/base-simple.predicate.spec.ts | 42 +-
.../predicate/simple/base-simple.predicate.ts | 46 +-
.../predicate/simple/equal.predicate.spec.ts | 118 +-
.../predicate/simple/equal.predicate.ts | 44 +-
.../src/lib/common/predicate/simple/index.ts | 4 +-
.../shared/src/lib/common/public-api.ts | 18 +-
.../shared/src/lib/common/route/index.ts | 2 +-
.../shared/src/lib/common/route/public-api.ts | 2 +-
.../src/lib/common/route/route.model.ts | 135 +-
.../shared/src/lib/common/service/index.ts | 2 +-
.../src/lib/common/service/model/index.ts | 2 +-
.../taurus-base-api-service.model.spec.ts | 380 +-
.../model/taurus-base-api-service.model.ts | 148 +-
.../src/lib/common/service/public-api.ts | 2 +-
.../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 | 95 +-
.../shared/src/lib/common/tasks/task.model.ts | 28 +-
.../src/lib/commons/css/screen-sizes.scss | 24 +-
.../shared/src/lib/commons/css/utils.scss | 14 +-
.../projects/shared/src/lib/commons/index.ts | 4 +-
.../ngx-components/animation-constants.ts | 30 +-
.../copy-to-clipboard-button.component.html | 97 +-
.../copy-to-clipboard-button.component.scss | 130 +-
...copy-to-clipboard-button.component.spec.ts | 134 +-
.../copy-to-clipboard-button.component.ts | 202 +-
.../copy-to-clipboard-button.l10n.ts | 72 +-
.../copy-to-clipboard-button/index.ts | 10 +-
.../copy-to-clipboard-button/public-api.ts | 2 +-
.../empty-state-placeholder.component.html | 10 +-
.../empty-state-placeholder.component.scss | 60 +-
.../empty-state-placeholder.component.ts | 16 +-
.../empty-state-placeholder.module.ts | 14 +-
.../empty-state-placeholder/index.ts | 4 +-
.../empty-state-placeholder/public-api.ts | 2 +-
.../form-section-container.component.html | 107 +-
.../form-section-container.component.scss | 10 +-
.../form-section-container.component.spec.ts | 346 +-
.../form-section-container.component.ts | 312 +-
.../form-section-container/index.ts | 10 +-
.../form-section-container/public-api.ts | 2 +-
.../form-section/form-section.component.html | 26 +-
.../form-section/form-section.component.scss | 48 +-
.../form-section.component.spec.ts | 112 +-
.../form-section/form-section.component.ts | 96 +-
.../ngx-components/form-section/index.ts | 6 +-
.../ngx-components/form-section/public-api.ts | 2 +-
.../src/lib/commons/ngx-components/index.ts | 14 +-
.../lib/commons/ngx-components/public-api.ts | 2 +-
.../commons/ngx-components/search/index.ts | 4 +-
.../ngx-components/search/public-api.ts | 2 +-
.../search/search.component.html | 107 +-
.../search/search.component.scss | 132 +-
.../search/search.component.spec.ts | 373 +-
.../ngx-components/search/search.component.ts | 236 +-
.../ngx-components/search/search.module.ts | 16 +-
.../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 | 50 +-
.../ngx-components/toast/toast.component.html | 261 +-
.../ngx-components/toast/toast.component.scss | 414 +-
.../ngx-components/toast/toast.component.ts | 573 +-
.../ngx-components/toast/toast.l10n.ts | 144 +-
.../ngx-components/toast/toast.model.ts | 8 +-
.../vdk-ngx-components.module.ts | 151 +-
.../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 | 22 +-
.../simple-translate.pipe.ts | 16 +-
.../simple-translate.service.spec.ts | 94 +-
.../simple-translate.service.ts | 149 +-
.../shared/src/lib/commons/public-api.ts | 2 +-
.../component/components/error-base/index.ts | 2 +-
.../taurus-error-base.component.spec.ts | 196 +-
.../error-base/taurus-error-base.component.ts | 145 +-
.../lib/core/component/components/index.ts | 4 +-
.../component/components/redux-base/index.ts | 4 +-
.../components/redux-base/interfaces/index.ts | 2 +-
...rus-component-lifecycle-hooks.interface.ts | 146 +-
.../redux-base/taurus-base.component.spec.ts | 1976 +-
.../redux-base/taurus-base.component.ts | 712 +-
.../shared/src/lib/core/component/index.ts | 8 +-
.../model/component-model.comparable.spec.ts | 475 +-
.../model/component-model.comparable.ts | 114 +-
.../model/component.model.interface.ts | 380 +-
.../component/model/component.model.spec.ts | 1062 +-
.../core/component/model/component.model.ts | 541 +-
.../src/lib/core/component/model/index.ts | 6 +-
.../model/state/component-state.model.spec.ts | 618 +-
.../model/state/component-state.model.ts | 837 +-
.../model/state/component-status.model.ts | 17 +-
.../state/components-state.model.spec.ts | 652 +-
.../model/state/components-state.model.ts | 493 +-
.../lib/core/component/model/state/index.ts | 6 +-
.../src/lib/core/component/public-api.ts | 2 +-
.../services/component.service.spec.ts | 1600 +-
.../component/services/component.service.ts | 714 +-
.../src/lib/core/component/services/index.ts | 2 +-
.../state/actions/component.actions.spec.ts | 452 +-
.../state/actions/component.actions.ts | 172 +-
.../lib/core/component/state/actions/index.ts | 2 +-
.../src/lib/core/component/state/index.ts | 6 +-
.../operators/component-rx.operators.spec.ts | 476 +-
.../state/operators/component-rx.operators.ts | 129 +-
.../core/component/state/operators/index.ts | 2 +-
.../state/reducers/component.reducer.spec.ts | 740 +-
.../state/reducers/component.reducer.ts | 278 +-
.../core/component/state/reducers/index.ts | 2 +-
.../shared/src/lib/core/error/index.ts | 4 +-
.../shared/src/lib/core/error/public-api.ts | 2 +-
.../store/model/error-store.impl.spec.ts | 2955 +-
.../error/store/model/error-store.impl.ts | 679 +-
.../src/lib/core/error/store/model/index.ts | 2 +-
.../lib/core/error/utils/error.utils.spec.ts | 979 +-
.../src/lib/core/error/utils/error.utils.ts | 214 +-
.../shared/src/lib/core/error/utils/index.ts | 2 +-
.../gui/projects/shared/src/lib/core/index.ts | 14 +-
.../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 | 783 +-
.../navigation/services/navigation.service.ts | 651 +-
.../core/ngrx/actions/base.actions.spec.ts | 132 +-
.../src/lib/core/ngrx/actions/base.actions.ts | 96 +-
.../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 | 41 +-
.../lib/core/ngrx/config/ngrx-config.model.ts | 30 +-
.../shared/src/lib/core/ngrx/effects/index.ts | 2 +-
.../src/lib/core/ngrx/effects/model/index.ts | 2 +-
.../effects/model/taurus-base.effects.spec.ts | 135 +-
.../ngrx/effects/model/taurus-base.effects.ts | 72 +-
.../effects/root-effects.registry.spec.ts | 14 +-
.../ngrx/effects/root-effects.registry.ts | 4 +-
.../src/lib/core/ngrx/helper-modules/index.ts | 4 +-
.../vdk-shared-ngrx-dev.module.ts | 88 +-
.../vdk-shared-ngrx-prod.module.ts | 58 +-
.../shared/src/lib/core/ngrx/index.ts | 6 +-
.../shared/src/lib/core/ngrx/public-api.ts | 6 +-
.../src/lib/core/ngrx/reducers/index.ts | 2 +-
.../shared-root-reducers.registry.spec.ts | 22 +-
.../reducers/shared-root-reducers.registry.ts | 12 +-
.../shared/src/lib/core/ngrx/state/index.ts | 2 +-
.../lib/core/ngrx/state/store-state.model.ts | 12 +-
.../lib/core/ngrx/vdk-shared-ngrx.module.ts | 139 +-
.../shared/src/lib/core/public-api.ts | 20 +-
.../src/lib/core/router/factory/index.ts | 2 +-
.../factory/route-state.factory.spec.ts | 82 +-
.../router/factory/route-state.factory.ts | 65 +-
.../shared/src/lib/core/router/index.ts | 6 +-
.../lib/core/router/integration/ngrx/index.ts | 2 +-
.../ngrx/router-serializer.service.spec.ts | 191 +-
.../ngrx/router-serializer.service.ts | 48 +-
.../shared/src/lib/core/router/model/index.ts | 2 +-
.../lib/core/router/model/route.model.spec.ts | 1347 +-
.../src/lib/core/router/model/route.model.ts | 793 +-
.../shared/src/lib/core/router/public-api.ts | 4 +-
.../src/lib/core/router/services/index.ts | 2 +-
.../router/services/router.service.spec.ts | 337 +-
.../core/router/services/router.service.ts | 134 +-
.../lib/core/router/state/actions/index.ts | 2 +-
.../state/actions/router.actions.spec.ts | 286 +-
.../router/state/actions/router.actions.ts | 112 +-
.../lib/core/router/state/effects/index.ts | 2 +-
.../state/effects/router.effects.spec.ts | 293 +-
.../router/state/effects/router.effects.ts | 160 +-
.../lib/core/router/state/reducers/index.ts | 2 +-
.../state/reducers/router.reducer.spec.ts | 66 +-
.../router/state/reducers/router.reducer.ts | 52 +-
.../event-handler-class.decorator.ts | 139 +-
.../decorator/event-handler.decorator.spec.ts | 116 +-
.../decorator/event-handler.decorator.ts | 76 +-
.../lib/core/system-events/decorator/index.ts | 4 +-
.../models/event-decorator-helper.ts | 3 +-
.../system-events/decorator/models/index.ts | 2 +-
.../dispatcher/event.dispatcher.spec.ts | 330 +-
.../dispatcher/event.dispatcher.ts | 245 +-
.../core/system-events/dispatcher/index.ts | 2 +-
.../models/event-dispatcher.model.ts | 49 +-
.../system-events/dispatcher/models/index.ts | 2 +-
.../registry/event-handler.registry.spec.ts | 470 +-
.../registry/event-handler.registry.ts | 467 +-
.../dispatcher/registry/index.ts | 2 +-
.../src/lib/core/system-events/event/index.ts | 2 +-
.../models/event-filter.expression.spec.ts | 245 +-
.../event/models/event-filter.expression.ts | 70 +-
.../system-events/event/models/event.codes.ts | 64 +-
.../event/models/event.comparable.spec.ts | 256 +-
.../event/models/event.comparable.ts | 64 +-
.../core/system-events/event/models/index.ts | 8 +-
.../src/lib/core/system-events/index.ts | 6 +-
.../src/lib/core/system-events/public-api.ts | 12 +-
.../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 | 490 +-
.../src/lib/core/vdk-shared-core.module.ts | 51 +-
.../src/lib/features/_model/features.model.ts | 4 +-
.../shared/src/lib/features/_model/index.ts | 2 +-
.../src/lib/features/_model/public-api.ts | 2 +-
.../src/lib/features/_token/features.token.ts | 7 +-
.../shared/src/lib/features/_token/index.ts | 2 +-
.../confirmation/confirmation.component.html | 188 +-
.../confirmation/confirmation.component.scss | 106 +-
.../confirmation.component.spec.ts | 755 +-
.../confirmation/confirmation.component.ts | 130 +-
.../confirmation-container.component.html | 12 +-
.../confirmation-container.component.scss | 46 +-
.../confirmation-container.component.spec.ts | 80 +-
.../confirmation-container.component.ts | 36 +-
.../features/confirmation/components/index.ts | 4 +-
.../confirmation/confirmation.module.ts | 19 +-
.../src/lib/features/confirmation/index.ts | 4 +-
.../model/confirmation.model.spec.ts | 6 +-
.../confirmation/model/confirmation.model.ts | 443 +-
.../lib/features/confirmation/model/index.ts | 5 +-
.../lib/features/confirmation/public-api.ts | 6 +-
.../services/confirmation.service.spec.ts | 1355 +-
.../services/confirmation.service.ts | 566 +-
.../features/confirmation/services/index.ts | 2 +-
.../features/directives/directives.module.ts | 12 +-
.../src/lib/features/directives/public-api.ts | 2 +-
.../dynamic-container.component.spec.ts | 54 +-
.../dynamic-container.component.ts | 27 +-
.../dynamic-context.component.spec.ts | 54 +-
.../dynamic-context.component.ts | 27 +-
.../dynamic-components/components/index.ts | 4 +-
.../dynamic-components.module.ts | 15 +-
.../lib/features/dynamic-components/index.ts | 2 +-
.../features/dynamic-components/public-api.ts | 4 +-
.../dynamic-components.service.spec.ts | 926 +-
.../services/dynamic-components.service.ts | 502 +-
.../dynamic-components/services/index.ts | 2 +-
.../lib/features/error-handler/public-api.ts | 2 +-
.../services/error-handler.service.spec.ts | 938 +-
.../services/error-handler.service.ts | 350 +-
.../features/error-handler/services/index.ts | 2 +-
.../src/lib/features/pipes/pipes.module.ts | 12 +-
.../src/lib/features/pipes/public-api.ts | 2 +-
.../empty-state/empty-state.component.html | 126 +-
.../empty-state/empty-state.component.scss | 60 +-
.../empty-state/empty-state.component.spec.ts | 36 +-
.../empty-state/empty-state.component.ts | 43 +-
.../components/empty-state/index.ts | 2 +-
.../features/placeholder/components/index.ts | 4 +-
.../components/placeholder.component.html | 2346 +-
.../components/placeholder.component.scss | 116 +-
.../components/placeholder.component.spec.ts | 105 +-
.../components/placeholder.component.ts | 1540 +-
.../src/lib/features/placeholder/index.ts | 4 +-
.../lib/features/placeholder/model/index.ts | 2 +-
.../placeholder/model/placeholder.model.ts | 14 +-
.../placeholder/placeholder.module.ts | 16 +-
.../lib/features/placeholder/public-api.ts | 4 +-
.../features/placeholder/services/index.ts | 2 +-
.../services/placeholder.service.spec.ts | 922 +-
.../services/placeholder.service.ts | 515 +-
.../shared/src/lib/features/public-api.ts | 22 +-
.../src/lib/features/toasts/model/index.ts | 2 +-
.../features/toasts/model/toast.interface.ts | 30 +-
.../src/lib/features/toasts/public-api.ts | 8 +-
.../src/lib/features/toasts/service/index.ts | 2 +-
.../toasts/service/toast.service.spec.ts | 54 +-
.../features/toasts/service/toast.service.ts | 34 +-
.../src/lib/features/toasts/toasts.module.ts | 23 +-
.../src/lib/features/toasts/widget/index.ts | 2 +-
.../toasts/widget/toasts.component.html | 62 +-
.../toasts/widget/toasts.component.scss | 16 +-
.../toasts/widget/toasts.component.spec.ts | 94 +-
.../toasts/widget/toasts.component.ts | 272 +-
.../src/lib/features/url-opener/index.ts | 4 +-
.../lib/features/url-opener/model/index.ts | 2 +-
.../url-opener/model/url-opener.model.ts | 20 +-
.../src/lib/features/url-opener/public-api.ts | 6 +-
.../lib/features/url-opener/services/index.ts | 2 +-
.../services/url-opener.service.spec.ts | 1042 +-
.../url-opener/services/url-opener.service.ts | 749 +-
.../features/url-opener/url-opener.module.ts | 6 +-
.../features/vdk-shared-features.module.ts | 155 +-
.../lib/features/warning/components/index.ts | 2 +-
.../warning/components/warning/index.ts | 2 +-
.../components/warning/warning.component.html | 133 +-
.../components/warning/warning.component.scss | 277 +-
.../warning/warning.component.spec.ts | 89 +-
.../components/warning/warning.component.ts | 312 +-
.../shared/src/lib/features/warning/index.ts | 4 +-
.../src/lib/features/warning/model/index.ts | 2 +-
.../features/warning/model/warning.model.ts | 14 +-
.../src/lib/features/warning/public-api.ts | 4 +-
.../lib/features/warning/warning.module.ts | 16 +-
.../shared/src/lib/unit-testing/index.ts | 2 +-
.../shared/src/lib/unit-testing/public-api.ts | 2 +-
.../utils/error-code-generator-utils.ts | 36 +-
.../src/lib/unit-testing/utils/index.ts | 6 +-
.../lib/unit-testing/utils/router-utils.ts | 204 +-
.../lib/unit-testing/utils/unit-test-utils.ts | 20 +-
.../collections/collections-util.spec.ts | 2415 +-
.../lib/utils/collections/collections-util.ts | 1001 +-
.../shared/src/lib/utils/collections/index.ts | 2 +-
.../projects/shared/src/lib/utils/index.ts | 6 +-
.../shared/src/lib/utils/model/data-source.ts | 24 +-
.../shared/src/lib/utils/model/index.ts | 4 +-
.../src/lib/utils/model/shorthand-types.ts | 86 +-
.../shared/src/lib/utils/public-api.ts | 6 +-
.../shared/src/lib/utils/url/index.ts | 2 +-
.../shared/src/lib/utils/url/url.util.spec.ts | 62 +-
.../shared/src/lib/utils/url/url.util.ts | 30 +-
.../gui/projects/shared/src/public-api.ts | 12 +-
.../gui/projects/shared/src/test.ts | 39 +-
projects/vdk-control-cli/setup.py | 4 +-
.../control/command_groups/job/execute.py | 14 +-
projects/vdk-control-cli/tests/conftest.py | 2 +-
projects/vdk-core/setup.py | 4 +-
.../builtin_plugins/connection/impl/router.py | 6 +-
projects/vdk-core/tests/conftest.py | 8 +-
projects/vdk-heartbeat/setup.py | 4 +-
.../internal/heartbeat/trino_database_test.py | 6 +-
.../vdk-plugins/vdk-dag/tests/conftest.py | 2 +-
.../vdk-plugins/vdk-duckdb/requirements.txt | 1 -
.../src/vdk/plugin/duckdb/ingest_to_duckdb.py | 8 +-
.../src/vdk/plugin/impala/impala_helper.py | 6 +-
.../templates/template_arguments_validator.py | 6 +-
.../vdk-jupyterlab-extension/.eslintrc.js | 56 +-
.../vdk-jupyterlab-extension/babel.config.js | 2 +-
.../vdk-jupyterlab-extension/jest.config.js | 54 +-
.../convert-job-to-notebook-component.spec.ts | 82 +-
.../__tests__/create-job-component.spec.ts | 54 +-
.../__tests__/deploy-job-component.spec.ts | 64 +-
.../__tests__/download-job-component.spec.ts | 58 +-
.../src/__tests__/handler.spec.ts | 68 +-
.../src/__tests__/resquests.spec.ts | 198 +-
.../src/__tests__/vdk-error-message.spec.ts | 68 +-
.../vdk-jupyterlab-extension.spec.ts | 4 +-
.../src/__tests__/vdk-tags.spec.ts | 94 +-
.../src/components/VdkErrorMessage.ts | 32 +-
.../vdk-jupyterlab-extension/src/handler.ts | 14 +-
.../vdk-jupyterlab-extension/src/index.ts | 46 +-
.../src/initVDKConfigCell.ts | 50 +-
.../vdk-jupyterlab-extension/src/jobData.ts | 16 +-
.../vdk-jupyterlab-extension/src/login.ts | 16 +-
.../src/serverRequests.ts | 110 +-
.../vdk-jupyterlab-extension/src/utils.ts | 44 +-
.../src/vdkOptions/vdk_options.ts | 10 +-
.../vdk-jupyterlab-extension/src/vdkTags.ts | 62 +-
.../vdk-jupyterlab-extension/style/base.css | 2 +-
.../vdk-jupyterlab-extension/style/index.css | 2 +-
.../vdk-jupyterlab-extension/style/index.js | 2 +-
.../testutils/jest-file-mock.js | 2 +-
.../testutils/jest-setup-files.js | 4 +-
.../ui-tests/playwright.config.js | 10 +-
.../ui-tests/tests/convert-job.spec.ts | 230 +-
.../ui-tests/tests/utils.ts | 4 +-
.../tests/vdk-jupyterlab-extension.spec.ts | 224 +-
.../src/vdk/plugin/sqlite/ingest_to_sqlite.py | 8 +-
.../src/vdk/plugin/trino/trino_config.py | 16 +-
741 files changed, 78799 insertions(+), 69708 deletions(-)
diff --git a/examples/pgvector-embedder/40_ingest_embeddings.py b/examples/pgvector-embedder/40_ingest_embeddings.py
index 289cb939c5..6ca5230043 100644
--- a/examples/pgvector-embedder/40_ingest_embeddings.py
+++ b/examples/pgvector-embedder/40_ingest_embeddings.py
@@ -41,9 +41,11 @@ def run(job_input: IJobInput):
embedding_payload = {
"id": composite_id,
- "embedding": embeddings[i].tolist()
- if isinstance(embeddings[i], np.ndarray)
- else embeddings[i],
+ "embedding": (
+ embeddings[i].tolist()
+ if isinstance(embeddings[i], np.ndarray)
+ else embeddings[i]
+ ),
}
job_input.send_object_for_ingestion(
payload=embedding_payload,
diff --git a/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/explore/data-jobs/data-jobs.spec.js b/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/explore/data-jobs/data-jobs.spec.js
index f5fbf51fe5..b6981555d8 100644
--- a/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/explore/data-jobs/data-jobs.spec.js
+++ b/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/explore/data-jobs/data-jobs.spec.js
@@ -5,10 +5,13 @@
///
-import { DataJobsExplorePage } from '../../../../support/pages/explore/data-jobs/data-jobs.po';
-import { DataJobExploreDetailsPage } from '../../../../support/pages/explore/data-jobs/details/data-job-details.po';
+import { DataJobsExplorePage } from "../../../../support/pages/explore/data-jobs/data-jobs.po";
+import { DataJobExploreDetailsPage } from "../../../../support/pages/explore/data-jobs/details/data-job-details.po";
-describe('Data Jobs Explore Page', { tags: ['@dataPipelines', '@exploreDataJobs', '@explore'] }, () => {
+describe(
+ "Data Jobs Explore Page",
+ { tags: ["@dataPipelines", "@exploreDataJobs", "@explore"] },
+ () => {
/**
* @type {DataJobsExplorePage}
*/
@@ -23,305 +26,464 @@ describe('Data Jobs Explore Page', { tags: ['@dataPipelines', '@exploreDataJobs'
let additionalTestJobFixture;
before(() => {
- return DataJobsExplorePage.recordHarIfSupported()
- .then(() => cy.clearLocalStorageSnapshot('data-jobs-explore'))
- .then(() => DataJobsExplorePage.login())
- .then(() => cy.saveLocalStorage('data-jobs-explore'))
- .then(() => DataJobsExplorePage.deleteShortLivedTestJobsNoDeploy(true))
- .then(() => DataJobsExplorePage.createShortLivedTestJobsNoDeploy())
- .then(() =>
- DataJobsExplorePage.loadShortLivedTestJobsFixtureNoDeploy().then((fixtures) => {
- testJobsFixture = [fixtures[0], fixtures[1]];
- additionalTestJobFixture = fixtures[2];
-
- return cy.wrap({
- context: 'explore::data-jobs.spec::before()',
- action: 'continue'
- });
- })
- );
+ return DataJobsExplorePage.recordHarIfSupported()
+ .then(() => cy.clearLocalStorageSnapshot("data-jobs-explore"))
+ .then(() => DataJobsExplorePage.login())
+ .then(() => cy.saveLocalStorage("data-jobs-explore"))
+ .then(() => DataJobsExplorePage.deleteShortLivedTestJobsNoDeploy(true))
+ .then(() => DataJobsExplorePage.createShortLivedTestJobsNoDeploy())
+ .then(() =>
+ DataJobsExplorePage.loadShortLivedTestJobsFixtureNoDeploy().then(
+ (fixtures) => {
+ testJobsFixture = [fixtures[0], fixtures[1]];
+ additionalTestJobFixture = fixtures[2];
+
+ return cy.wrap({
+ context: "explore::data-jobs.spec::before()",
+ action: "continue",
+ });
+ },
+ ),
+ );
});
after(() => {
- DataJobsExplorePage.deleteShortLivedTestJobsNoDeploy();
+ DataJobsExplorePage.deleteShortLivedTestJobsNoDeploy();
- DataJobsExplorePage.saveHarIfSupported();
+ DataJobsExplorePage.saveHarIfSupported();
});
beforeEach(() => {
- cy.restoreLocalStorage('data-jobs-explore');
+ cy.restoreLocalStorage("data-jobs-explore");
- DataJobsExplorePage.wireUserSession();
- DataJobsExplorePage.initInterceptors();
+ DataJobsExplorePage.wireUserSession();
+ DataJobsExplorePage.initInterceptors();
});
- describe('smoke', { tags: ['@smoke'] }, () => {
- it('page is loaded and shows data jobs', () => {
- dataJobsExplorePage = DataJobsExplorePage.navigateWithSideMenu();
+ describe("smoke", { tags: ["@smoke"] }, () => {
+ it("page is loaded and shows data jobs", () => {
+ dataJobsExplorePage = DataJobsExplorePage.navigateWithSideMenu();
- dataJobsExplorePage.getPageTitle().scrollIntoView().should('be.visible').invoke('text').invoke('trim').should('eq', 'Explore Data Jobs');
+ dataJobsExplorePage
+ .getPageTitle()
+ .scrollIntoView()
+ .should("be.visible")
+ .invoke("text")
+ .invoke("trim")
+ .should("eq", "Explore Data Jobs");
- dataJobsExplorePage.getDataGrid().scrollIntoView().should('be.visible');
+ dataJobsExplorePage.getDataGrid().scrollIntoView().should("be.visible");
- // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
- dataJobsExplorePage.filterByJobName(testJobsFixture[0].job_name.substring(0, 20));
+ // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
+ dataJobsExplorePage.filterByJobName(
+ testJobsFixture[0].job_name.substring(0, 20),
+ );
- testJobsFixture.forEach((testJob) => {
- cy.log('Fixture for name: ' + testJob.job_name);
+ testJobsFixture.forEach((testJob) => {
+ cy.log("Fixture for name: " + testJob.job_name);
- dataJobsExplorePage.getDataGridCell(testJob.job_name).scrollIntoView().should('be.visible');
- });
+ dataJobsExplorePage
+ .getDataGridCell(testJob.job_name)
+ .scrollIntoView()
+ .should("be.visible");
});
+ });
- it('navigates to data job', () => {
- cy.log('Fixture for name: ' + testJobsFixture[0].job_name);
+ it("navigates to data job", () => {
+ cy.log("Fixture for name: " + testJobsFixture[0].job_name);
- dataJobsExplorePage = DataJobsExplorePage.navigateTo();
+ dataJobsExplorePage = DataJobsExplorePage.navigateTo();
- // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
- dataJobsExplorePage.filterByJobName(testJobsFixture[0].job_name.substring(0, 20));
+ // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
+ dataJobsExplorePage.filterByJobName(
+ testJobsFixture[0].job_name.substring(0, 20),
+ );
- dataJobsExplorePage.openJobDetails(testJobsFixture[0].team, testJobsFixture[0].job_name);
+ dataJobsExplorePage.openJobDetails(
+ testJobsFixture[0].team,
+ testJobsFixture[0].job_name,
+ );
- const dataJobExploreDetailsPage = DataJobExploreDetailsPage.getPage();
+ const dataJobExploreDetailsPage = DataJobExploreDetailsPage.getPage();
- dataJobExploreDetailsPage.getPageTitle().scrollIntoView().should('be.visible').should('contains.text', testJobsFixture[0].job_name);
+ dataJobExploreDetailsPage
+ .getPageTitle()
+ .scrollIntoView()
+ .should("be.visible")
+ .should("contains.text", testJobsFixture[0].job_name);
- dataJobExploreDetailsPage.getDescriptionField().scrollIntoView().should('be.visible').should('contain.text', testJobsFixture[0].description);
- });
+ dataJobExploreDetailsPage
+ .getDescriptionField()
+ .scrollIntoView()
+ .should("be.visible")
+ .should("contain.text", testJobsFixture[0].description);
+ });
});
- describe('extended', () => {
- it('refresh load newly created data jobs', () => {
- dataJobsExplorePage = DataJobsExplorePage.navigateTo();
-
- // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
- dataJobsExplorePage.filterByJobName(testJobsFixture[0].job_name.substring(0, 20));
-
- dataJobsExplorePage.getDataGridCell(testJobsFixture[0].job_name).invoke('text').invoke('trim').should('eq', testJobsFixture[0].job_name);
-
- dataJobsExplorePage.getDataGridCell(additionalTestJobFixture.job_name).should('not.exist');
-
- DataJobsExplorePage.createAdditionalShortLivedTestJobsNoDeploy();
-
- dataJobsExplorePage.refreshDataGrid();
-
- dataJobsExplorePage.getDataGridCell(additionalTestJobFixture.job_name).invoke('text').invoke('trim').should('eq', additionalTestJobFixture.job_name);
- });
-
- it('filters data jobs', () => {
- cy.log('Fixture for name: ' + testJobsFixture[0].job_name);
-
- dataJobsExplorePage = DataJobsExplorePage.navigateTo();
-
- dataJobsExplorePage.filterByJobName(testJobsFixture[0].job_name);
-
- dataJobsExplorePage.getDataGridCell(testJobsFixture[0].job_name).scrollIntoView().should('be.visible');
-
- dataJobsExplorePage.getDataGridCell(testJobsFixture[1].job_name).should('not.exist');
- });
-
- it('searches data jobs', () => {
- cy.log('Fixture for name: ' + testJobsFixture[0].job_name);
-
- dataJobsExplorePage = DataJobsExplorePage.navigateTo();
-
- // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
- dataJobsExplorePage.filterByJobName(testJobsFixture[1].job_name.substring(0, 20));
-
- dataJobsExplorePage.getDataGridCell(testJobsFixture[1].job_name).scrollIntoView().should('be.visible');
-
- // verify url contains jobName value
- dataJobsExplorePage.getCurrentUrl().should('match', new RegExp(`\\/explore\\/data-jobs\\?jobName=${testJobsFixture[1].job_name.substring(0, 20)}&deploymentStatus=all$`));
-
- dataJobsExplorePage.searchByJobName(testJobsFixture[0].job_name);
-
- dataJobsExplorePage.getDataGridCell(testJobsFixture[0].job_name).scrollIntoView().should('be.visible');
-
- dataJobsExplorePage.getDataGridCell(testJobsFixture[1].job_name).should('not.exist');
- });
-
- it('searches data jobs, search parameter goes into URL', () => {
- cy.log('Fixture for name: ' + testJobsFixture[0].job_name);
-
- dataJobsExplorePage = DataJobsExplorePage.navigateTo();
-
- // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
- dataJobsExplorePage.filterByJobName(testJobsFixture[0].job_name.substring(0, 20));
-
- // verify 2 test rows visible
- dataJobsExplorePage.getDataGridCell(testJobsFixture[0].job_name).scrollIntoView().should('be.visible');
- dataJobsExplorePage.getDataGridCell(testJobsFixture[1].job_name).scrollIntoView().should('be.visible');
-
- // do search
- dataJobsExplorePage.searchByJobName(testJobsFixture[0].job_name);
-
- // verify 1 test row visible
- dataJobsExplorePage.getDataGridCell(testJobsFixture[0].job_name).scrollIntoView().should('be.visible');
- dataJobsExplorePage.getDataGridCell(testJobsFixture[1].job_name).should('not.exist');
-
- // verify url contains search value
- dataJobsExplorePage.getCurrentUrl().should('match', new RegExp(`\\/explore\\/data-jobs\\?search=${testJobsFixture[0].job_name}&jobName=${testJobsFixture[0].job_name.substring(0, 20)}&deploymentStatus=all$`));
-
- // clear search with clear() method
- dataJobsExplorePage.clearSearchField();
-
- // verify 2 test rows visible
- dataJobsExplorePage.getDataGridCell(testJobsFixture[0].job_name).scrollIntoView().should('be.visible');
- dataJobsExplorePage.getDataGridCell(testJobsFixture[1].job_name).scrollIntoView().should('be.visible');
-
- // verify url does not contain search value
- dataJobsExplorePage.getCurrentUrl().should('match', new RegExp(`\\/explore\\/data-jobs\\?jobName=${testJobsFixture[0].job_name.substring(0, 20)}&deploymentStatus=all$`));
- });
-
- it('searches data jobs, perform search when URL contains search parameter', () => {
- cy.log('Fixture for name: ' + testJobsFixture[1].job_name);
-
- // navigate with search value in URL
- dataJobsExplorePage = DataJobsExplorePage.navigateToDataJobUrl(`/explore/data-jobs?search=${testJobsFixture[1].job_name}`);
-
- dataJobsExplorePage.waitForGridToLoad(null);
-
- // verify url contains search value
- dataJobsExplorePage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: '/explore/data-jobs',
- queryParams: {
- search: testJobsFixture[1].job_name,
- deploymentStatus: 'all'
- }
- });
-
- // verify 1 test row visible
- dataJobsExplorePage.getDataGridCell(testJobsFixture[0].job_name).should('not.exist');
- dataJobsExplorePage.getDataGridCell(testJobsFixture[1].job_name).scrollIntoView().should('be.visible');
-
- // clear search with button
- dataJobsExplorePage.clearSearchFieldWithButton();
-
- // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
- dataJobsExplorePage.filterByJobName(testJobsFixture[0].job_name.substring(0, 20));
-
- // verify 2 test rows visible
- dataJobsExplorePage.getDataGridCell(testJobsFixture[0].job_name).scrollIntoView().should('be.visible');
- dataJobsExplorePage.getDataGridCell(testJobsFixture[1].job_name).scrollIntoView().should('be.visible');
-
- // verify url does not contain search value
- dataJobsExplorePage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: '/explore/data-jobs',
- queryParams: {
- jobName: testJobsFixture[0].job_name.substring(0, 20),
- deploymentStatus: 'all'
- }
- });
- });
-
- it('filter description data jobs', () => {
- dataJobsExplorePage = DataJobsExplorePage.navigateTo();
-
- // show panel for show/hide columns
- dataJobsExplorePage.toggleColumnShowHidePanel();
-
- // verify column is not checked in toggling menu
- dataJobsExplorePage.getDataGridColumnShowHideOption('Description').should('exist').should('not.be.checked');
-
- // verify header cell for column is not rendered
- dataJobsExplorePage.getDataGridHeaderCell('Description').should('have.length', 0);
-
- // toggle column to render
- dataJobsExplorePage.checkColumnShowHideOption('Description');
-
- // verify column is checked in toggling menu
- dataJobsExplorePage.getHeaderColumnDescriptionName().should('exist');
-
- // filter by job description
- dataJobsExplorePage.filterByJobDescription('Test description 1');
-
- // verify url contains description value
- dataJobsExplorePage.getCurrentUrl().should('match', new RegExp(`\\/explore\\/data-jobs\\?description=Test%20description%201&deploymentStatus=all$`));
-
- dataJobsExplorePage.getDataGridCell(testJobsFixture[0].job_name).scrollIntoView().should('be.visible');
-
- dataJobsExplorePage.getDataGridCell(testJobsFixture[1].job_name).should('not.exist');
- });
-
- it('perform filtering by description when URL contains description parameter', () => {
- // navigate with description value in URL
- dataJobsExplorePage = DataJobsExplorePage.navigateToDataJobUrl(`/explore/data-jobs?description=Test%20description%201`);
-
- dataJobsExplorePage.waitForGridToLoad(null);
-
- // show panel for show/hide columns
- dataJobsExplorePage.toggleColumnShowHidePanel();
-
- // toggle column to render
- dataJobsExplorePage.checkColumnShowHideOption('Description');
-
- // verify url contains description value
- dataJobsExplorePage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: '/explore/data-jobs',
- queryParams: {
- description: 'Test description 1',
- deploymentStatus: 'all'
- }
- });
-
- // verify 1 test row visible
- dataJobsExplorePage.getDataGridCell(testJobsFixture[0].job_name).scrollIntoView().should('be.visible');
-
- dataJobsExplorePage.getDataGridCell(testJobsFixture[1].job_name).should('not.exist');
- });
-
- it('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', 10).invoke('join', ',').should('eq', 'Description,Deployment Status,Python Version,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();
- });
+ describe("extended", () => {
+ it("refresh load newly created data jobs", () => {
+ dataJobsExplorePage = DataJobsExplorePage.navigateTo();
+
+ // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
+ dataJobsExplorePage.filterByJobName(
+ testJobsFixture[0].job_name.substring(0, 20),
+ );
+
+ dataJobsExplorePage
+ .getDataGridCell(testJobsFixture[0].job_name)
+ .invoke("text")
+ .invoke("trim")
+ .should("eq", testJobsFixture[0].job_name);
+
+ dataJobsExplorePage
+ .getDataGridCell(additionalTestJobFixture.job_name)
+ .should("not.exist");
+
+ DataJobsExplorePage.createAdditionalShortLivedTestJobsNoDeploy();
+
+ dataJobsExplorePage.refreshDataGrid();
+
+ dataJobsExplorePage
+ .getDataGridCell(additionalTestJobFixture.job_name)
+ .invoke("text")
+ .invoke("trim")
+ .should("eq", additionalTestJobFixture.job_name);
+ });
+
+ it("filters data jobs", () => {
+ cy.log("Fixture for name: " + testJobsFixture[0].job_name);
+
+ dataJobsExplorePage = DataJobsExplorePage.navigateTo();
+
+ dataJobsExplorePage.filterByJobName(testJobsFixture[0].job_name);
+
+ dataJobsExplorePage
+ .getDataGridCell(testJobsFixture[0].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+
+ dataJobsExplorePage
+ .getDataGridCell(testJobsFixture[1].job_name)
+ .should("not.exist");
+ });
+
+ it("searches data jobs", () => {
+ cy.log("Fixture for name: " + testJobsFixture[0].job_name);
+
+ dataJobsExplorePage = DataJobsExplorePage.navigateTo();
+
+ // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
+ dataJobsExplorePage.filterByJobName(
+ testJobsFixture[1].job_name.substring(0, 20),
+ );
+
+ dataJobsExplorePage
+ .getDataGridCell(testJobsFixture[1].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+
+ // verify url contains jobName value
+ dataJobsExplorePage
+ .getCurrentUrl()
+ .should(
+ "match",
+ new RegExp(
+ `\\/explore\\/data-jobs\\?jobName=${testJobsFixture[1].job_name.substring(0, 20)}&deploymentStatus=all$`,
+ ),
+ );
+
+ dataJobsExplorePage.searchByJobName(testJobsFixture[0].job_name);
+
+ dataJobsExplorePage
+ .getDataGridCell(testJobsFixture[0].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+
+ dataJobsExplorePage
+ .getDataGridCell(testJobsFixture[1].job_name)
+ .should("not.exist");
+ });
+
+ it("searches data jobs, search parameter goes into URL", () => {
+ cy.log("Fixture for name: " + testJobsFixture[0].job_name);
+
+ dataJobsExplorePage = DataJobsExplorePage.navigateTo();
+
+ // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
+ dataJobsExplorePage.filterByJobName(
+ testJobsFixture[0].job_name.substring(0, 20),
+ );
+
+ // verify 2 test rows visible
+ dataJobsExplorePage
+ .getDataGridCell(testJobsFixture[0].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+ dataJobsExplorePage
+ .getDataGridCell(testJobsFixture[1].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+
+ // do search
+ dataJobsExplorePage.searchByJobName(testJobsFixture[0].job_name);
+
+ // verify 1 test row visible
+ dataJobsExplorePage
+ .getDataGridCell(testJobsFixture[0].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+ dataJobsExplorePage
+ .getDataGridCell(testJobsFixture[1].job_name)
+ .should("not.exist");
+
+ // verify url contains search value
+ dataJobsExplorePage
+ .getCurrentUrl()
+ .should(
+ "match",
+ new RegExp(
+ `\\/explore\\/data-jobs\\?search=${testJobsFixture[0].job_name}&jobName=${testJobsFixture[0].job_name.substring(0, 20)}&deploymentStatus=all$`,
+ ),
+ );
+
+ // clear search with clear() method
+ dataJobsExplorePage.clearSearchField();
+
+ // verify 2 test rows visible
+ dataJobsExplorePage
+ .getDataGridCell(testJobsFixture[0].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+ dataJobsExplorePage
+ .getDataGridCell(testJobsFixture[1].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+
+ // verify url does not contain search value
+ dataJobsExplorePage
+ .getCurrentUrl()
+ .should(
+ "match",
+ new RegExp(
+ `\\/explore\\/data-jobs\\?jobName=${testJobsFixture[0].job_name.substring(0, 20)}&deploymentStatus=all$`,
+ ),
+ );
+ });
+
+ it("searches data jobs, perform search when URL contains search parameter", () => {
+ cy.log("Fixture for name: " + testJobsFixture[1].job_name);
+
+ // navigate with search value in URL
+ dataJobsExplorePage = DataJobsExplorePage.navigateToDataJobUrl(
+ `/explore/data-jobs?search=${testJobsFixture[1].job_name}`,
+ );
+
+ dataJobsExplorePage.waitForGridToLoad(null);
+
+ // verify url contains search value
+ dataJobsExplorePage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: "/explore/data-jobs",
+ queryParams: {
+ search: testJobsFixture[1].job_name,
+ deploymentStatus: "all",
+ },
+ });
+
+ // verify 1 test row visible
+ dataJobsExplorePage
+ .getDataGridCell(testJobsFixture[0].job_name)
+ .should("not.exist");
+ dataJobsExplorePage
+ .getDataGridCell(testJobsFixture[1].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+
+ // clear search with button
+ dataJobsExplorePage.clearSearchFieldWithButton();
+
+ // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
+ dataJobsExplorePage.filterByJobName(
+ testJobsFixture[0].job_name.substring(0, 20),
+ );
+
+ // verify 2 test rows visible
+ dataJobsExplorePage
+ .getDataGridCell(testJobsFixture[0].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+ dataJobsExplorePage
+ .getDataGridCell(testJobsFixture[1].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+
+ // verify url does not contain search value
+ dataJobsExplorePage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: "/explore/data-jobs",
+ queryParams: {
+ jobName: testJobsFixture[0].job_name.substring(0, 20),
+ deploymentStatus: "all",
+ },
+ });
+ });
+
+ it("filter description data jobs", () => {
+ dataJobsExplorePage = DataJobsExplorePage.navigateTo();
+
+ // show panel for show/hide columns
+ dataJobsExplorePage.toggleColumnShowHidePanel();
+
+ // verify column is not checked in toggling menu
+ dataJobsExplorePage
+ .getDataGridColumnShowHideOption("Description")
+ .should("exist")
+ .should("not.be.checked");
+
+ // verify header cell for column is not rendered
+ dataJobsExplorePage
+ .getDataGridHeaderCell("Description")
+ .should("have.length", 0);
+
+ // toggle column to render
+ dataJobsExplorePage.checkColumnShowHideOption("Description");
+
+ // verify column is checked in toggling menu
+ dataJobsExplorePage.getHeaderColumnDescriptionName().should("exist");
+
+ // filter by job description
+ dataJobsExplorePage.filterByJobDescription("Test description 1");
+
+ // verify url contains description value
+ dataJobsExplorePage
+ .getCurrentUrl()
+ .should(
+ "match",
+ new RegExp(
+ `\\/explore\\/data-jobs\\?description=Test%20description%201&deploymentStatus=all$`,
+ ),
+ );
+
+ dataJobsExplorePage
+ .getDataGridCell(testJobsFixture[0].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+
+ dataJobsExplorePage
+ .getDataGridCell(testJobsFixture[1].job_name)
+ .should("not.exist");
+ });
+
+ it("perform filtering by description when URL contains description parameter", () => {
+ // navigate with description value in URL
+ dataJobsExplorePage = DataJobsExplorePage.navigateToDataJobUrl(
+ `/explore/data-jobs?description=Test%20description%201`,
+ );
+
+ dataJobsExplorePage.waitForGridToLoad(null);
+
+ // show panel for show/hide columns
+ dataJobsExplorePage.toggleColumnShowHidePanel();
+
+ // toggle column to render
+ dataJobsExplorePage.checkColumnShowHideOption("Description");
+
+ // verify url contains description value
+ dataJobsExplorePage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: "/explore/data-jobs",
+ queryParams: {
+ description: "Test description 1",
+ deploymentStatus: "all",
+ },
+ });
+
+ // verify 1 test row visible
+ dataJobsExplorePage
+ .getDataGridCell(testJobsFixture[0].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+
+ dataJobsExplorePage
+ .getDataGridCell(testJobsFixture[1].job_name)
+ .should("not.exist");
+ });
+
+ it("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", 10)
+ .invoke("join", ",")
+ .should(
+ "eq",
+ "Description,Deployment Status,Python Version,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();
+ });
});
-});
+ },
+);
diff --git a/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/explore/data-jobs/details/data-job-details.spec.js b/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/explore/data-jobs/details/data-job-details.spec.js
index 90d867f2b6..c5685bfb10 100644
--- a/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/explore/data-jobs/details/data-job-details.spec.js
+++ b/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/explore/data-jobs/details/data-job-details.spec.js
@@ -5,10 +5,13 @@
///
-import { DataJobsExplorePage } from '../../../../../support/pages/explore/data-jobs/data-jobs.po';
-import { DataJobExploreDetailsPage } from '../../../../../support/pages/explore/data-jobs/details/data-job-details.po';
+import { DataJobsExplorePage } from "../../../../../support/pages/explore/data-jobs/data-jobs.po";
+import { DataJobExploreDetailsPage } from "../../../../../support/pages/explore/data-jobs/details/data-job-details.po";
-describe('Data Job Explore Details Page', { tags: ['@dataPipelines', '@exploreDataJobDetails', '@explore'] }, () => {
+describe(
+ "Data Job Explore Details Page",
+ { tags: ["@dataPipelines", "@exploreDataJobDetails", "@explore"] },
+ () => {
/**
* @type {DataJobExploreDetailsPage}
*/
@@ -23,101 +26,191 @@ describe('Data Job Explore Details Page', { tags: ['@dataPipelines', '@exploreDa
let dataJobsExplorePage;
before(() => {
- return DataJobExploreDetailsPage.recordHarIfSupported()
- .then(() => cy.clearLocalStorageSnapshot('data-job-explore-details'))
- .then(() => DataJobExploreDetailsPage.login())
- .then(() => cy.saveLocalStorage('data-job-explore-details'))
- .then(() => DataJobExploreDetailsPage.deleteShortLivedTestJobsNoDeploy(true))
- .then(() => DataJobExploreDetailsPage.createShortLivedTestJobsNoDeploy())
- .then(() =>
- DataJobExploreDetailsPage.loadShortLivedTestJobsFixtureNoDeploy().then((fixtures) => {
- testJobsFixture = [fixtures[0], fixtures[1]];
-
- return cy.wrap({
- context: 'explore::data-job-details.spec::before()',
- action: 'continue'
- });
- })
- );
+ return DataJobExploreDetailsPage.recordHarIfSupported()
+ .then(() => cy.clearLocalStorageSnapshot("data-job-explore-details"))
+ .then(() => DataJobExploreDetailsPage.login())
+ .then(() => cy.saveLocalStorage("data-job-explore-details"))
+ .then(() =>
+ DataJobExploreDetailsPage.deleteShortLivedTestJobsNoDeploy(true),
+ )
+ .then(() =>
+ DataJobExploreDetailsPage.createShortLivedTestJobsNoDeploy(),
+ )
+ .then(() =>
+ DataJobExploreDetailsPage.loadShortLivedTestJobsFixtureNoDeploy().then(
+ (fixtures) => {
+ testJobsFixture = [fixtures[0], fixtures[1]];
+
+ return cy.wrap({
+ context: "explore::data-job-details.spec::before()",
+ action: "continue",
+ });
+ },
+ ),
+ );
});
after(() => {
- DataJobExploreDetailsPage.deleteShortLivedTestJobsNoDeploy();
+ DataJobExploreDetailsPage.deleteShortLivedTestJobsNoDeploy();
- DataJobExploreDetailsPage.saveHarIfSupported();
+ DataJobExploreDetailsPage.saveHarIfSupported();
});
beforeEach(() => {
- cy.restoreLocalStorage('data-job-explore-details');
+ cy.restoreLocalStorage("data-job-explore-details");
- DataJobExploreDetailsPage.wireUserSession();
- DataJobExploreDetailsPage.initInterceptors();
+ DataJobExploreDetailsPage.wireUserSession();
+ DataJobExploreDetailsPage.initInterceptors();
});
- describe('smoke', { tags: ['@smoke'] }, () => {
- it('should load and show job details', () => {
- dataJobsExplorePage = DataJobsExplorePage.navigateWithSideMenu();
-
- // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
- dataJobsExplorePage.filterByJobName(testJobsFixture[0].job_name.substring(0, 20));
-
- dataJobsExplorePage.openJobDetails(testJobsFixture[0].team, testJobsFixture[0].job_name);
-
- dataJobExploreDetailsPage = DataJobExploreDetailsPage.getPage();
-
- dataJobExploreDetailsPage.getDetailsTab().scrollIntoView().should('be.visible');
-
- dataJobExploreDetailsPage.getPageTitle().scrollIntoView().should('be.visible').should('contains.text', testJobsFixture[0].job_name);
-
- dataJobExploreDetailsPage.getStatusField().scrollIntoView().should('be.visible').should('have.text', 'Not Deployed');
-
- dataJobExploreDetailsPage.getDescriptionField().scrollIntoView().should('be.visible').should('contain.text', testJobsFixture[0].description);
-
- dataJobExploreDetailsPage.getTeamField().scrollIntoView().should('be.visible').should('have.text', testJobsFixture[0].team);
-
- dataJobExploreDetailsPage.getScheduleField().scrollIntoView().should('be.visible').should('contains.text', 'At 12:00 AM, on day 01 of the month, and on Friday');
-
- dataJobExploreDetailsPage.getOnDeployedField().scrollIntoView().should('be.visible').should('contains.text', testJobsFixture[0].config.contacts.notified_on_job_deploy);
-
- dataJobExploreDetailsPage.getOnPlatformErrorField().scrollIntoView().should('be.visible').should('contains.text', testJobsFixture[0].config.contacts.notified_on_job_failure_platform_error);
-
- dataJobExploreDetailsPage.getOnUserErrorField().scrollIntoView().should('be.visible').should('contains.text', testJobsFixture[0].config.contacts.notified_on_job_failure_user_error);
-
- dataJobExploreDetailsPage.getOnSuccessField().scrollIntoView().should('be.visible').should('contains.text', testJobsFixture[0].config.contacts.notified_on_job_success);
- });
-
- it('should verify Details tab is visible and active', () => {
- dataJobsExplorePage = DataJobsExplorePage.navigateTo();
-
- // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
- dataJobsExplorePage.filterByJobName(testJobsFixture[0].job_name.substring(0, 20));
-
- dataJobsExplorePage.openJobDetails(testJobsFixture[0].team, testJobsFixture[0].job_name);
-
- const dataJobExploreDetailsPage = DataJobExploreDetailsPage.getPage();
-
- dataJobExploreDetailsPage.getPageTitle().scrollIntoView().should('be.visible').should('contains.text', testJobsFixture[0].job_name);
-
- dataJobExploreDetailsPage.getDetailsTab().scrollIntoView().should('be.visible').should('have.class', 'active');
- });
+ describe("smoke", { tags: ["@smoke"] }, () => {
+ it("should load and show job details", () => {
+ dataJobsExplorePage = DataJobsExplorePage.navigateWithSideMenu();
+
+ // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
+ dataJobsExplorePage.filterByJobName(
+ testJobsFixture[0].job_name.substring(0, 20),
+ );
+
+ dataJobsExplorePage.openJobDetails(
+ testJobsFixture[0].team,
+ testJobsFixture[0].job_name,
+ );
+
+ dataJobExploreDetailsPage = DataJobExploreDetailsPage.getPage();
+
+ dataJobExploreDetailsPage
+ .getDetailsTab()
+ .scrollIntoView()
+ .should("be.visible");
+
+ dataJobExploreDetailsPage
+ .getPageTitle()
+ .scrollIntoView()
+ .should("be.visible")
+ .should("contains.text", testJobsFixture[0].job_name);
+
+ dataJobExploreDetailsPage
+ .getStatusField()
+ .scrollIntoView()
+ .should("be.visible")
+ .should("have.text", "Not Deployed");
+
+ dataJobExploreDetailsPage
+ .getDescriptionField()
+ .scrollIntoView()
+ .should("be.visible")
+ .should("contain.text", testJobsFixture[0].description);
+
+ dataJobExploreDetailsPage
+ .getTeamField()
+ .scrollIntoView()
+ .should("be.visible")
+ .should("have.text", testJobsFixture[0].team);
+
+ dataJobExploreDetailsPage
+ .getScheduleField()
+ .scrollIntoView()
+ .should("be.visible")
+ .should(
+ "contains.text",
+ "At 12:00 AM, on day 01 of the month, and on Friday",
+ );
+
+ dataJobExploreDetailsPage
+ .getOnDeployedField()
+ .scrollIntoView()
+ .should("be.visible")
+ .should(
+ "contains.text",
+ testJobsFixture[0].config.contacts.notified_on_job_deploy,
+ );
+
+ dataJobExploreDetailsPage
+ .getOnPlatformErrorField()
+ .scrollIntoView()
+ .should("be.visible")
+ .should(
+ "contains.text",
+ testJobsFixture[0].config.contacts
+ .notified_on_job_failure_platform_error,
+ );
+
+ dataJobExploreDetailsPage
+ .getOnUserErrorField()
+ .scrollIntoView()
+ .should("be.visible")
+ .should(
+ "contains.text",
+ testJobsFixture[0].config.contacts
+ .notified_on_job_failure_user_error,
+ );
+
+ dataJobExploreDetailsPage
+ .getOnSuccessField()
+ .scrollIntoView()
+ .should("be.visible")
+ .should(
+ "contains.text",
+ testJobsFixture[0].config.contacts.notified_on_job_success,
+ );
+ });
+
+ it("should verify Details tab is visible and active", () => {
+ dataJobsExplorePage = DataJobsExplorePage.navigateTo();
+
+ // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
+ dataJobsExplorePage.filterByJobName(
+ testJobsFixture[0].job_name.substring(0, 20),
+ );
+
+ dataJobsExplorePage.openJobDetails(
+ testJobsFixture[0].team,
+ testJobsFixture[0].job_name,
+ );
+
+ const dataJobExploreDetailsPage = DataJobExploreDetailsPage.getPage();
+
+ dataJobExploreDetailsPage
+ .getPageTitle()
+ .scrollIntoView()
+ .should("be.visible")
+ .should("contains.text", testJobsFixture[0].job_name);
+
+ dataJobExploreDetailsPage
+ .getDetailsTab()
+ .scrollIntoView()
+ .should("be.visible")
+ .should("have.class", "active");
+ });
});
- describe('extended', () => {
- it('should verify Action buttons are not displayed', () => {
- dataJobsExplorePage = DataJobsExplorePage.navigateTo();
+ describe("extended", () => {
+ it("should verify Action buttons are not displayed", () => {
+ dataJobsExplorePage = DataJobsExplorePage.navigateTo();
- // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
- dataJobsExplorePage.filterByJobName(testJobsFixture[0].job_name.substring(0, 20));
+ // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
+ dataJobsExplorePage.filterByJobName(
+ testJobsFixture[0].job_name.substring(0, 20),
+ );
- dataJobsExplorePage.openJobDetails(testJobsFixture[0].team, testJobsFixture[0].job_name);
+ dataJobsExplorePage.openJobDetails(
+ testJobsFixture[0].team,
+ testJobsFixture[0].job_name,
+ );
- const dataJobExploreDetailsPage = DataJobExploreDetailsPage.getPage();
+ const dataJobExploreDetailsPage = DataJobExploreDetailsPage.getPage();
- dataJobExploreDetailsPage.getPageTitle().scrollIntoView().should('be.visible').should('contains.text', testJobsFixture[0].job_name);
+ dataJobExploreDetailsPage
+ .getPageTitle()
+ .scrollIntoView()
+ .should("be.visible")
+ .should("contains.text", testJobsFixture[0].job_name);
- dataJobExploreDetailsPage.getExecuteNowButton().should('not.exist');
+ dataJobExploreDetailsPage.getExecuteNowButton().should("not.exist");
- dataJobExploreDetailsPage.getActionDropdownBtn().should('not.exist');
- });
+ dataJobExploreDetailsPage.getActionDropdownBtn().should("not.exist");
+ });
});
-});
+ },
+);
diff --git a/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/explore/data-jobs/executions/data-job-executions.spec.js b/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/explore/data-jobs/executions/data-job-executions.spec.js
index 1e3e3b0cd9..296712c474 100644
--- a/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/explore/data-jobs/executions/data-job-executions.spec.js
+++ b/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/explore/data-jobs/executions/data-job-executions.spec.js
@@ -5,93 +5,119 @@
///
-import { DataJobDetailsBasePO } from '../../../../../support/pages/base/data-pipelines/data-job-details-base.po';
+import { DataJobDetailsBasePO } from "../../../../../support/pages/base/data-pipelines/data-job-details-base.po";
-import { DataJobsExplorePage } from '../../../../../support/pages/explore/data-jobs/data-jobs.po';
-import { DataJobExploreExecutionsPage } from '../../../../../support/pages/explore/data-jobs/executions/data-job-executions.po';
+import { DataJobsExplorePage } from "../../../../../support/pages/explore/data-jobs/data-jobs.po";
+import { DataJobExploreExecutionsPage } from "../../../../../support/pages/explore/data-jobs/executions/data-job-executions.po";
-describe('Data Job Explore Executions Page', { tags: ['@dataPipelines', '@exploreDataJobExecutions', '@explore'] }, () => {
+describe(
+ "Data Job Explore Executions Page",
+ { tags: ["@dataPipelines", "@exploreDataJobExecutions", "@explore"] },
+ () => {
/**
* @type {Array<{job_name:string; description:string; team:string; config:{db_default_type:string; contacts:{}; schedule:{schedule_cron:string}; generate_keytab:boolean; enable_execution_notifications:boolean}}>}
*/
let testJobsFixture;
before(() => {
- return DataJobExploreExecutionsPage.recordHarIfSupported()
- .then(() => cy.clearLocalStorageSnapshot('data-job-explore-executions'))
- .then(() => DataJobExploreExecutionsPage.login())
- .then(() => cy.saveLocalStorage('data-job-explore-executions'))
- .then(() => DataJobExploreExecutionsPage.deleteShortLivedTestJobsNoDeploy(true))
- .then(() => DataJobExploreExecutionsPage.createShortLivedTestJobsNoDeploy())
- .then(() =>
- DataJobExploreExecutionsPage.loadShortLivedTestJobsFixtureNoDeploy().then((fixtures) => {
- testJobsFixture = [fixtures[0], fixtures[1]];
-
- return cy.wrap({
- context: 'explore::data-job-executions.spec::before()',
- action: 'continue'
- });
- })
- );
+ return DataJobExploreExecutionsPage.recordHarIfSupported()
+ .then(() => cy.clearLocalStorageSnapshot("data-job-explore-executions"))
+ .then(() => DataJobExploreExecutionsPage.login())
+ .then(() => cy.saveLocalStorage("data-job-explore-executions"))
+ .then(() =>
+ DataJobExploreExecutionsPage.deleteShortLivedTestJobsNoDeploy(true),
+ )
+ .then(() =>
+ DataJobExploreExecutionsPage.createShortLivedTestJobsNoDeploy(),
+ )
+ .then(() =>
+ DataJobExploreExecutionsPage.loadShortLivedTestJobsFixtureNoDeploy().then(
+ (fixtures) => {
+ testJobsFixture = [fixtures[0], fixtures[1]];
+
+ return cy.wrap({
+ context: "explore::data-job-executions.spec::before()",
+ action: "continue",
+ });
+ },
+ ),
+ );
});
after(() => {
- DataJobExploreExecutionsPage.deleteShortLivedTestJobsNoDeploy();
+ DataJobExploreExecutionsPage.deleteShortLivedTestJobsNoDeploy();
- DataJobExploreExecutionsPage.saveHarIfSupported();
+ DataJobExploreExecutionsPage.saveHarIfSupported();
});
beforeEach(() => {
- cy.restoreLocalStorage('data-job-explore-executions');
+ cy.restoreLocalStorage("data-job-explore-executions");
- DataJobExploreExecutionsPage.wireUserSession();
- DataJobExploreExecutionsPage.initInterceptors();
+ DataJobExploreExecutionsPage.wireUserSession();
+ DataJobExploreExecutionsPage.initInterceptors();
});
- describe('smoke', { tags: ['@smoke'] }, () => {
- it(`should open Details and verify Executions tab is not displayed`, () => {
- cy.log('Fixture for name: ' + testJobsFixture[0].job_name);
+ describe("smoke", { tags: ["@smoke"] }, () => {
+ it(`should open Details and verify Executions tab is not displayed`, () => {
+ cy.log("Fixture for name: " + testJobsFixture[0].job_name);
- /**
- * @type {DataJobsExplorePage}
- */
- const dataJobsExplorePage = DataJobsExplorePage.navigateWithSideMenu();
+ /**
+ * @type {DataJobsExplorePage}
+ */
+ const dataJobsExplorePage = DataJobsExplorePage.navigateWithSideMenu();
- // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
- dataJobsExplorePage.filterByJobName(testJobsFixture[0].job_name.substring(0, 20));
+ // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
+ dataJobsExplorePage.filterByJobName(
+ testJobsFixture[0].job_name.substring(0, 20),
+ );
- dataJobsExplorePage.openJobDetails(testJobsFixture[0].team, testJobsFixture[0].job_name);
+ dataJobsExplorePage.openJobDetails(
+ testJobsFixture[0].team,
+ testJobsFixture[0].job_name,
+ );
- const dataJobDetailsBasePage = DataJobDetailsBasePO.getPage();
+ const dataJobDetailsBasePage = DataJobDetailsBasePO.getPage();
- dataJobDetailsBasePage.getPageTitle().scrollIntoView().should('be.visible').should('contains.text', testJobsFixture[0].job_name);
+ dataJobDetailsBasePage
+ .getPageTitle()
+ .scrollIntoView()
+ .should("be.visible")
+ .should("contains.text", testJobsFixture[0].job_name);
- dataJobDetailsBasePage.getDetailsTab().should('have.class', 'active');
+ dataJobDetailsBasePage.getDetailsTab().should("have.class", "active");
- dataJobDetailsBasePage.getExecutionsTab().should('not.exist');
- });
+ dataJobDetailsBasePage.getExecutionsTab().should("not.exist");
+ });
});
- describe('extended', () => {
- it('should verify on URL navigate to Executions will redirect to Details', () => {
- /**
- * @type {DataJobExploreExecutionsPage}
- */
- const dataJobBasePage = DataJobExploreExecutionsPage.navigateTo(testJobsFixture[0].team, testJobsFixture[0].job_name);
-
- dataJobBasePage.getPageTitle().scrollIntoView().should('be.visible').should('contains.text', testJobsFixture[0].job_name);
-
- dataJobBasePage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/explore/data-jobs/${testJobsFixture[0].team}/${testJobsFixture[0].job_name}/details`,
- queryParams: {}
- });
-
- dataJobBasePage.getDetailsTab().should('have.class', 'active');
- });
+ describe("extended", () => {
+ it("should verify on URL navigate to Executions will redirect to Details", () => {
+ /**
+ * @type {DataJobExploreExecutionsPage}
+ */
+ const dataJobBasePage = DataJobExploreExecutionsPage.navigateTo(
+ testJobsFixture[0].team,
+ testJobsFixture[0].job_name,
+ );
+
+ dataJobBasePage
+ .getPageTitle()
+ .scrollIntoView()
+ .should("be.visible")
+ .should("contains.text", testJobsFixture[0].job_name);
+
+ dataJobBasePage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/explore/data-jobs/${testJobsFixture[0].team}/${testJobsFixture[0].job_name}/details`,
+ queryParams: {},
+ });
+
+ dataJobBasePage.getDetailsTab().should("have.class", "active");
+ });
});
-});
+ },
+);
diff --git a/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/get-started/get-started-page-data-jobs-health-overview.spec.js b/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/get-started/get-started-page-data-jobs-health-overview.spec.js
index 2d5fd19926..b4bca65971 100644
--- a/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/get-started/get-started-page-data-jobs-health-overview.spec.js
+++ b/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/get-started/get-started-page-data-jobs-health-overview.spec.js
@@ -5,13 +5,16 @@
///
-import { TEAM_VDK_DATA_JOB_FAILING } from '../../../support/helpers/constants.support';
+import { TEAM_VDK_DATA_JOB_FAILING } from "../../../support/helpers/constants.support";
-import { GetStartedDataJobsHealthOverviewWidgetPO } from '../../../support/pages/get-started/get-started-page-data-jobs-health-overview.po';
-import { DataJobManageDetailsPage } from '../../../support/pages/manage/data-jobs/details/data-job-details.po';
-import { DataJobManageExecutionsPage } from '../../../support/pages/manage/data-jobs/executions/data-job-executions.po';
+import { GetStartedDataJobsHealthOverviewWidgetPO } from "../../../support/pages/get-started/get-started-page-data-jobs-health-overview.po";
+import { DataJobManageDetailsPage } from "../../../support/pages/manage/data-jobs/details/data-job-details.po";
+import { DataJobManageExecutionsPage } from "../../../support/pages/manage/data-jobs/executions/data-job-executions.po";
-describe('Get Started Page: Data Jobs Health Overview Widget', { tags: ['@dataPipelines', '@healthOverviewWidget', '@getStarted'] }, () => {
+describe(
+ "Get Started Page: Data Jobs Health Overview Widget",
+ { tags: ["@dataPipelines", "@healthOverviewWidget", "@getStarted"] },
+ () => {
/**
* @type {{job_name:string; description:string; team:string; config:{db_default_type:string; contacts:{}; schedule:{schedule_cron:string}; generate_keytab:boolean; enable_execution_notifications:boolean}}}
*/
@@ -22,101 +25,167 @@ describe('Get Started Page: Data Jobs Health Overview Widget', { tags: ['@dataPi
let getStartedPage;
before(() => {
- return GetStartedDataJobsHealthOverviewWidgetPO.recordHarIfSupported()
- .then(() => cy.clearLocalStorageSnapshot('get-started-page-data-jobs-health'))
- .then(() => GetStartedDataJobsHealthOverviewWidgetPO.login())
- .then(() => cy.saveLocalStorage('get-started-page-data-jobs-health'))
- .then(() => GetStartedDataJobsHealthOverviewWidgetPO.createLongLivedJobs('failing'))
- .then(() => GetStartedDataJobsHealthOverviewWidgetPO.provideExecutionsForLongLivedJobs({ job: 'failing' }))
- .then(() =>
- GetStartedDataJobsHealthOverviewWidgetPO.loadLongLivedFailingJobFixture().then((loadedTestJob) => {
- longLivedFailingJobFixture = loadedTestJob;
-
- return cy.wrap({
- context: 'get-started::1::get-started-page-data-jobs-health-overview.spec::before()',
- action: 'continue'
- });
- })
- )
- .then(() => {
- return cy.wrap({
- context: 'get-started::2::get-started-page-data-jobs-health-overview.spec::before()',
- action: 'continue'
- });
- });
+ return GetStartedDataJobsHealthOverviewWidgetPO.recordHarIfSupported()
+ .then(() =>
+ cy.clearLocalStorageSnapshot("get-started-page-data-jobs-health"),
+ )
+ .then(() => GetStartedDataJobsHealthOverviewWidgetPO.login())
+ .then(() => cy.saveLocalStorage("get-started-page-data-jobs-health"))
+ .then(() =>
+ GetStartedDataJobsHealthOverviewWidgetPO.createLongLivedJobs(
+ "failing",
+ ),
+ )
+ .then(() =>
+ GetStartedDataJobsHealthOverviewWidgetPO.provideExecutionsForLongLivedJobs(
+ { job: "failing" },
+ ),
+ )
+ .then(() =>
+ GetStartedDataJobsHealthOverviewWidgetPO.loadLongLivedFailingJobFixture().then(
+ (loadedTestJob) => {
+ longLivedFailingJobFixture = loadedTestJob;
+
+ return cy.wrap({
+ context:
+ "get-started::1::get-started-page-data-jobs-health-overview.spec::before()",
+ action: "continue",
+ });
+ },
+ ),
+ )
+ .then(() => {
+ return cy.wrap({
+ context:
+ "get-started::2::get-started-page-data-jobs-health-overview.spec::before()",
+ action: "continue",
+ });
+ });
});
after(() => {
- return GetStartedDataJobsHealthOverviewWidgetPO.saveHarIfSupported().then(() =>
- cy.wrap({
- context: 'get-started::get-started-page-data-jobs-health-overview.spec::after()',
- action: 'continue'
- })
- );
+ return GetStartedDataJobsHealthOverviewWidgetPO.saveHarIfSupported().then(
+ () =>
+ cy.wrap({
+ context:
+ "get-started::get-started-page-data-jobs-health-overview.spec::after()",
+ action: "continue",
+ }),
+ );
});
beforeEach(() => {
- cy.restoreLocalStorage('get-started-page-data-jobs-health');
+ cy.restoreLocalStorage("get-started-page-data-jobs-health");
- GetStartedDataJobsHealthOverviewWidgetPO.wireUserSession();
- GetStartedDataJobsHealthOverviewWidgetPO.initInterceptors();
+ GetStartedDataJobsHealthOverviewWidgetPO.wireUserSession();
+ GetStartedDataJobsHealthOverviewWidgetPO.initInterceptors();
- getStartedPage = GetStartedDataJobsHealthOverviewWidgetPO.navigateTo();
+ getStartedPage = GetStartedDataJobsHealthOverviewWidgetPO.navigateTo();
});
- describe('smoke', { tags: ['@smoke'] }, () => {
- it('Validate Data Jobs Health Overview panel', () => {
- getStartedPage.getPageTitle().should('contain.text', 'Get Started with Data Pipelines');
-
- getStartedPage.getDataJobsHealthPanel().scrollIntoView();
-
- getStartedPage.getNumberOfFailedExecutions().should('be.gt', 0);
- getStartedPage
- .getAllFailingJobs()
- .then((elements) => elements.filter((_index, el) => el.innerText.includes(TEAM_VDK_DATA_JOB_FAILING)))
- .should('have.length.gt', 0);
- getStartedPage
- .getAllMostRecentFailingJobs()
- .then((elements) => elements.filter((_index, el) => el.innerText.includes(TEAM_VDK_DATA_JOB_FAILING)))
- .should('have.length.gt', 0);
- });
+ describe("smoke", { tags: ["@smoke"] }, () => {
+ it("Validate Data Jobs Health Overview panel", () => {
+ getStartedPage
+ .getPageTitle()
+ .should("contain.text", "Get Started with Data Pipelines");
+
+ getStartedPage.getDataJobsHealthPanel().scrollIntoView();
+
+ getStartedPage.getNumberOfFailedExecutions().should("be.gt", 0);
+ getStartedPage
+ .getAllFailingJobs()
+ .then((elements) =>
+ elements.filter((_index, el) =>
+ el.innerText.includes(TEAM_VDK_DATA_JOB_FAILING),
+ ),
+ )
+ .should("have.length.gt", 0);
+ getStartedPage
+ .getAllMostRecentFailingJobs()
+ .then((elements) =>
+ elements.filter((_index, el) =>
+ el.innerText.includes(TEAM_VDK_DATA_JOB_FAILING),
+ ),
+ )
+ .should("have.length.gt", 0);
+ });
});
- describe('extended', () => {
- it('Verify Widgets rendered correct data and failing jobs navigates correctly', () => {
- getStartedPage.getDataJobsHealthPanel().scrollIntoView();
-
- getStartedPage.getExecutionsSuccessPercentage().should('be.gte', 0).should('be.lte', 100);
- getStartedPage.getNumberOfFailedExecutions().should('be.gte', 2);
- getStartedPage.getExecutionsTotal().should('be.gte', 2);
-
- getStartedPage.getAllFailingJobs().should('have.length.gte', 1);
+ describe("extended", () => {
+ it("Verify Widgets rendered correct data and failing jobs navigates correctly", () => {
+ getStartedPage.getDataJobsHealthPanel().scrollIntoView();
- getStartedPage.getAllMostRecentFailingJobsLinks().should('have.length.gte', 1);
+ getStartedPage
+ .getExecutionsSuccessPercentage()
+ .should("be.gte", 0)
+ .should("be.lte", 100);
+ getStartedPage.getNumberOfFailedExecutions().should("be.gte", 2);
+ getStartedPage.getExecutionsTotal().should("be.gte", 2);
- // navigate to failing job details
- getStartedPage.navigateToFailingJobDetails(longLivedFailingJobFixture.job_name);
+ getStartedPage.getAllFailingJobs().should("have.length.gte", 1);
- const dataJobManageDetailsPage = DataJobManageDetailsPage.getPage();
- dataJobManageDetailsPage.getPageTitle().should('contain.text', `Data Job: ${longLivedFailingJobFixture.job_name}`);
- dataJobManageDetailsPage.getDetailsTab().should('be.visible').should('have.class', 'active');
- dataJobManageDetailsPage.getExecutionsTab().should('exist').should('not.have.class', 'active');
- dataJobManageDetailsPage.showMoreDescription().getDescriptionFull().should('contain.text', longLivedFailingJobFixture.description);
- });
-
- it('Verify most recent failing executions Widget navigates correctly', () => {
- getStartedPage.getDataJobsHealthPanel().scrollIntoView();
+ getStartedPage
+ .getAllMostRecentFailingJobsLinks()
+ .should("have.length.gte", 1);
- getStartedPage.getAllMostRecentFailingJobsLinks().should('have.length.gte', 1);
+ // navigate to failing job details
+ getStartedPage.navigateToFailingJobDetails(
+ longLivedFailingJobFixture.job_name,
+ );
- // navigate to most recent failing job executions
- getStartedPage.navigateToMostRecentFailingJobExecutions(longLivedFailingJobFixture.job_name);
+ const dataJobManageDetailsPage = DataJobManageDetailsPage.getPage();
+ dataJobManageDetailsPage
+ .getPageTitle()
+ .should(
+ "contain.text",
+ `Data Job: ${longLivedFailingJobFixture.job_name}`,
+ );
+ dataJobManageDetailsPage
+ .getDetailsTab()
+ .should("be.visible")
+ .should("have.class", "active");
+ dataJobManageDetailsPage
+ .getExecutionsTab()
+ .should("exist")
+ .should("not.have.class", "active");
+ dataJobManageDetailsPage
+ .showMoreDescription()
+ .getDescriptionFull()
+ .should("contain.text", longLivedFailingJobFixture.description);
+ });
+
+ it("Verify most recent failing executions Widget navigates correctly", () => {
+ getStartedPage.getDataJobsHealthPanel().scrollIntoView();
+
+ getStartedPage
+ .getAllMostRecentFailingJobsLinks()
+ .should("have.length.gte", 1);
+
+ // navigate to most recent failing job executions
+ getStartedPage.navigateToMostRecentFailingJobExecutions(
+ longLivedFailingJobFixture.job_name,
+ );
- const dataJobManageExecutionsPage = DataJobManageExecutionsPage.getPage();
- dataJobManageExecutionsPage.getPageTitle().should('contain.text', `Data Job: ${longLivedFailingJobFixture.job_name}`);
- dataJobManageExecutionsPage.getDetailsTab().should('be.visible').should('not.have.class', 'active');
- dataJobManageExecutionsPage.getExecutionsTab().should('be.visible').should('have.class', 'active');
- dataJobManageExecutionsPage.getDataGridRows().should('have.length.gte', 2);
- });
+ const dataJobManageExecutionsPage =
+ DataJobManageExecutionsPage.getPage();
+ dataJobManageExecutionsPage
+ .getPageTitle()
+ .should(
+ "contain.text",
+ `Data Job: ${longLivedFailingJobFixture.job_name}`,
+ );
+ dataJobManageExecutionsPage
+ .getDetailsTab()
+ .should("be.visible")
+ .should("not.have.class", "active");
+ dataJobManageExecutionsPage
+ .getExecutionsTab()
+ .should("be.visible")
+ .should("have.class", "active");
+ dataJobManageExecutionsPage
+ .getDataGridRows()
+ .should("have.length.gte", 2);
+ });
});
-});
+ },
+);
diff --git a/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/get-started/get-started-page.spec.js b/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/get-started/get-started-page.spec.js
index be191f2e14..62f5a1b8a3 100644
--- a/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/get-started/get-started-page.spec.js
+++ b/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/get-started/get-started-page.spec.js
@@ -5,46 +5,54 @@
///
-import { GetStartedPagePO } from '../../../support/pages/get-started/get-started-page.po';
+import { GetStartedPagePO } from "../../../support/pages/get-started/get-started-page.po";
-describe('Get Started Page', { tags: ['@dataPipelines', '@getStarted'] }, () => {
+describe(
+ "Get Started Page",
+ { tags: ["@dataPipelines", "@getStarted"] },
+ () => {
/**
* @type {GetStartedPagePO}
*/
let getStartedPage;
before(() => {
- return GetStartedPagePO.recordHarIfSupported()
- .then(() => cy.clearLocalStorageSnapshot('get-started-page'))
- .then(() => cy.saveLocalStorage('get-started-page'))
- .then(() => {
- return cy.wrap({
- context: 'get-started::1::get-started-page.spec::before()',
- action: 'continue'
- });
- });
+ return GetStartedPagePO.recordHarIfSupported()
+ .then(() => cy.clearLocalStorageSnapshot("get-started-page"))
+ .then(() => cy.saveLocalStorage("get-started-page"))
+ .then(() => {
+ return cy.wrap({
+ context: "get-started::1::get-started-page.spec::before()",
+ action: "continue",
+ });
+ });
});
after(() => {
- return GetStartedPagePO.saveHarIfSupported().then(() =>
- cy.wrap({
- context: 'get-started::get-started-page.spec::after()',
- action: 'continue'
- })
- );
+ return GetStartedPagePO.saveHarIfSupported().then(() =>
+ cy.wrap({
+ context: "get-started::get-started-page.spec::after()",
+ action: "continue",
+ }),
+ );
});
beforeEach(() => {
- cy.restoreLocalStorage('get-started-page');
+ cy.restoreLocalStorage("get-started-page");
- GetStartedPagePO.wireUserSession();
- GetStartedPagePO.initInterceptors();
- getStartedPage = GetStartedPagePO.navigateTo();
+ GetStartedPagePO.wireUserSession();
+ GetStartedPagePO.initInterceptors();
+ getStartedPage = GetStartedPagePO.navigateTo();
});
- describe('smoke', { tags: ['@smoke'] }, () => {
- it('Main Title Component have text: Get Started with Data Pipelines', () => {
- getStartedPage.getPageTitle().invoke('text').invoke('trim').should('eq', 'Get Started with Data Pipelines');
- });
+ describe("smoke", { tags: ["@smoke"] }, () => {
+ it("Main Title Component have text: Get Started with Data Pipelines", () => {
+ getStartedPage
+ .getPageTitle()
+ .invoke("text")
+ .invoke("trim")
+ .should("eq", "Get Started with Data Pipelines");
+ });
});
-});
+ },
+);
diff --git a/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/manage/data-jobs/data-jobs.spec.js b/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/manage/data-jobs/data-jobs.spec.js
index 61ebbeb02a..374515f4af 100644
--- a/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/manage/data-jobs/data-jobs.spec.js
+++ b/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/manage/data-jobs/data-jobs.spec.js
@@ -5,10 +5,13 @@
///
-import { DataJobsManagePage } from '../../../../support/pages/manage/data-jobs/data-jobs.po';
-import { DataJobManageDetailsPage } from '../../../../support/pages/manage/data-jobs/details/data-job-details.po';
+import { DataJobsManagePage } from "../../../../support/pages/manage/data-jobs/data-jobs.po";
+import { DataJobManageDetailsPage } from "../../../../support/pages/manage/data-jobs/details/data-job-details.po";
-describe('Data Jobs Manage Page', { tags: ['@dataPipelines', '@manageDataJobs', '@manage'] }, () => {
+describe(
+ "Data Jobs Manage Page",
+ { tags: ["@dataPipelines", "@manageDataJobs", "@manage"] },
+ () => {
const descriptionWordsBeforeTruncate = 12;
/**
@@ -29,445 +32,628 @@ describe('Data Jobs Manage Page', { tags: ['@dataPipelines', '@manageDataJobs',
let shortLivedTestJobWithDeployFixture;
before(() => {
- return DataJobsManagePage.recordHarIfSupported()
- .then(() => cy.clearLocalStorageSnapshot('data-jobs-manage'))
- .then(() => DataJobsManagePage.login())
- .then(() => cy.saveLocalStorage('data-jobs-manage'))
- .then(() => DataJobsManagePage.deleteShortLivedTestJobsNoDeploy(true))
- .then(() => DataJobsManagePage.createLongLivedJobs('failing'))
- .then(() => DataJobsManagePage.createShortLivedTestJobWithDeploy('v0'))
- .then(() =>
- DataJobsManagePage.loadShortLivedTestJobFixtureWithDeploy('v0').then((loadedTestJob) => {
- shortLivedTestJobWithDeployFixture = loadedTestJob;
-
- return cy.wrap({
- context: 'manage::1::data-jobs.int.spec::before()',
- action: 'continue'
- });
- })
- )
- .then(() => DataJobsManagePage.createShortLivedTestJobsNoDeploy())
- .then(() =>
- DataJobsManagePage.loadShortLivedTestJobsFixtureNoDeploy().then((fixtures) => {
- testJobsFixture = [fixtures[0], fixtures[1]];
- additionalTestJobFixture = fixtures[2];
-
- return cy.wrap({
- context: 'manage::2::data-jobs.int.spec::before()',
- action: 'continue'
- });
- })
- );
+ return DataJobsManagePage.recordHarIfSupported()
+ .then(() => cy.clearLocalStorageSnapshot("data-jobs-manage"))
+ .then(() => DataJobsManagePage.login())
+ .then(() => cy.saveLocalStorage("data-jobs-manage"))
+ .then(() => DataJobsManagePage.deleteShortLivedTestJobsNoDeploy(true))
+ .then(() => DataJobsManagePage.createLongLivedJobs("failing"))
+ .then(() => DataJobsManagePage.createShortLivedTestJobWithDeploy("v0"))
+ .then(() =>
+ DataJobsManagePage.loadShortLivedTestJobFixtureWithDeploy("v0").then(
+ (loadedTestJob) => {
+ shortLivedTestJobWithDeployFixture = loadedTestJob;
+
+ return cy.wrap({
+ context: "manage::1::data-jobs.int.spec::before()",
+ action: "continue",
+ });
+ },
+ ),
+ )
+ .then(() => DataJobsManagePage.createShortLivedTestJobsNoDeploy())
+ .then(() =>
+ DataJobsManagePage.loadShortLivedTestJobsFixtureNoDeploy().then(
+ (fixtures) => {
+ testJobsFixture = [fixtures[0], fixtures[1]];
+ additionalTestJobFixture = fixtures[2];
+
+ return cy.wrap({
+ context: "manage::2::data-jobs.int.spec::before()",
+ action: "continue",
+ });
+ },
+ ),
+ );
});
after(() => {
- DataJobsManagePage.deleteShortLivedTestJobWithDeploy('v0');
- DataJobsManagePage.deleteShortLivedTestJobsNoDeploy();
+ DataJobsManagePage.deleteShortLivedTestJobWithDeploy("v0");
+ DataJobsManagePage.deleteShortLivedTestJobsNoDeploy();
- DataJobsManagePage.saveHarIfSupported();
+ DataJobsManagePage.saveHarIfSupported();
});
beforeEach(() => {
- cy.restoreLocalStorage('data-jobs-manage');
+ cy.restoreLocalStorage("data-jobs-manage");
- DataJobsManagePage.wireUserSession();
- DataJobsManagePage.initInterceptors();
+ DataJobsManagePage.wireUserSession();
+ DataJobsManagePage.initInterceptors();
});
- describe('smoke', { tags: ['@smoke'] }, () => {
- it('page is loaded and grid contains test jobs', () => {
- dataJobsManagePage = DataJobsManagePage.navigateWithSideMenu();
+ describe("smoke", { tags: ["@smoke"] }, () => {
+ it("page is loaded and grid contains test jobs", () => {
+ dataJobsManagePage = DataJobsManagePage.navigateWithSideMenu();
- dataJobsManagePage.getPageTitle().scrollIntoView().should('be.visible').invoke('text').invoke('trim').should('eq', 'Manage Data Jobs');
+ dataJobsManagePage
+ .getPageTitle()
+ .scrollIntoView()
+ .should("be.visible")
+ .invoke("text")
+ .invoke("trim")
+ .should("eq", "Manage Data Jobs");
- dataJobsManagePage.chooseQuickFilter(0);
+ dataJobsManagePage.chooseQuickFilter(0);
- // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
- dataJobsManagePage.filterByJobName(testJobsFixture[0].job_name.substring(0, 20));
+ // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
+ dataJobsManagePage.filterByJobName(
+ testJobsFixture[0].job_name.substring(0, 20),
+ );
- dataJobsManagePage.getDataGrid().scrollIntoView().should('be.visible');
+ dataJobsManagePage.getDataGrid().scrollIntoView().should("be.visible");
- testJobsFixture.forEach((testJob) => {
- cy.log('Fixture for name: ' + testJob.job_name);
+ testJobsFixture.forEach((testJob) => {
+ cy.log("Fixture for name: " + testJob.job_name);
- dataJobsManagePage.getDataGridCell(testJob.job_name).scrollIntoView().should('be.visible');
- });
+ dataJobsManagePage
+ .getDataGridCell(testJob.job_name)
+ .scrollIntoView()
+ .should("be.visible");
});
+ });
- it('grid filters by job name', () => {
- dataJobsManagePage = DataJobsManagePage.navigateTo();
+ it("grid filters by job name", () => {
+ dataJobsManagePage = DataJobsManagePage.navigateTo();
- dataJobsManagePage.chooseQuickFilter(0);
+ dataJobsManagePage.chooseQuickFilter(0);
- // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
- dataJobsManagePage.filterByJobName(testJobsFixture[0].job_name);
+ // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
+ dataJobsManagePage.filterByJobName(testJobsFixture[0].job_name);
- dataJobsManagePage.getDataGridCell(testJobsFixture[0].job_name).scrollIntoView().should('be.visible');
+ dataJobsManagePage
+ .getDataGridCell(testJobsFixture[0].job_name)
+ .scrollIntoView()
+ .should("be.visible");
- dataJobsManagePage.getDataGridCell(testJobsFixture[1].job_name).should('not.exist');
- });
+ dataJobsManagePage
+ .getDataGridCell(testJobsFixture[1].job_name)
+ .should("not.exist");
+ });
- it('grid searches by job name', () => {
- dataJobsManagePage = DataJobsManagePage.navigateTo();
+ it("grid searches by job name", () => {
+ dataJobsManagePage = DataJobsManagePage.navigateTo();
- dataJobsManagePage.chooseQuickFilter(0);
+ dataJobsManagePage.chooseQuickFilter(0);
- dataJobsManagePage.searchByJobName(testJobsFixture[1].job_name);
+ dataJobsManagePage.searchByJobName(testJobsFixture[1].job_name);
- dataJobsManagePage.getDataGridCell(testJobsFixture[0].job_name).should('not.exist');
+ dataJobsManagePage
+ .getDataGridCell(testJobsFixture[0].job_name)
+ .should("not.exist");
- dataJobsManagePage.getDataGridCell(testJobsFixture[1].job_name).scrollIntoView().should('be.visible');
- });
+ dataJobsManagePage
+ .getDataGridCell(testJobsFixture[1].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+ });
- it('disable/enable job', () => {
- dataJobsManagePage = DataJobsManagePage.navigateTo();
+ it("disable/enable job", () => {
+ dataJobsManagePage = DataJobsManagePage.navigateTo();
- dataJobsManagePage.chooseQuickFilter(0);
+ dataJobsManagePage.chooseQuickFilter(0);
- const jobName = shortLivedTestJobWithDeployFixture.job_name;
+ const jobName = shortLivedTestJobWithDeployFixture.job_name;
- // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
- dataJobsManagePage.filterByJobName(shortLivedTestJobWithDeployFixture.job_name.substring(0, 20));
+ // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
+ dataJobsManagePage.filterByJobName(
+ shortLivedTestJobWithDeployFixture.job_name.substring(0, 20),
+ );
- //Toggle job status twice, enable to disable and vice versa.
- dataJobsManagePage.toggleJobStatus(shortLivedTestJobWithDeployFixture.job_name);
- dataJobsManagePage.toggleJobStatus(shortLivedTestJobWithDeployFixture.job_name);
- });
+ //Toggle job status twice, enable to disable and vice versa.
+ dataJobsManagePage.toggleJobStatus(
+ shortLivedTestJobWithDeployFixture.job_name,
+ );
+ dataJobsManagePage.toggleJobStatus(
+ shortLivedTestJobWithDeployFixture.job_name,
+ );
+ });
});
- describe('extended', () => {
- it('grid search parameter goes into URL', () => {
- dataJobsManagePage = DataJobsManagePage.navigateTo();
-
- dataJobsManagePage.chooseQuickFilter(0);
-
- // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
- dataJobsManagePage.filterByJobName(testJobsFixture[0].job_name.substring(0, 20));
-
- // verify 2 test rows visible
- dataJobsManagePage.getDataGridCell(testJobsFixture[0].job_name).scrollIntoView().should('be.visible');
- dataJobsManagePage.getDataGridCell(testJobsFixture[1].job_name).scrollIntoView().should('be.visible');
-
- // do search
- dataJobsManagePage.searchByJobName(testJobsFixture[0].job_name);
-
- // verify 1 test row visible
- dataJobsManagePage.getDataGridCell(testJobsFixture[0].job_name).scrollIntoView().should('be.visible');
- dataJobsManagePage.getDataGridCell(testJobsFixture[1].job_name).should('not.exist');
-
- // verify url contains search value
- dataJobsManagePage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: '/manage/data-jobs',
- queryParams: {
- search: testJobsFixture[0].job_name,
- jobName: testJobsFixture[0].job_name.substring(0, 20),
- deploymentStatus: 'all'
- }
- });
-
- // clear search with clear() method
- dataJobsManagePage.clearSearchField();
-
- // verify 2 test rows visible
- dataJobsManagePage.getDataGridCell(testJobsFixture[0].job_name).scrollIntoView().should('be.visible');
- dataJobsManagePage.getDataGridCell(testJobsFixture[1].job_name).scrollIntoView().should('be.visible');
-
- // verify url does not contain search value
- dataJobsManagePage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: '/manage/data-jobs',
- queryParams: {
- jobName: testJobsFixture[0].job_name.substring(0, 20),
- deploymentStatus: 'all'
- }
- });
- });
-
- it('grid search perform search when URL contains search parameter', () => {
- // navigate with search value in URL
- dataJobsManagePage = DataJobsManagePage.navigateToDataJobUrl(`/manage/data-jobs?search=${testJobsFixture[1].job_name}`);
-
- dataJobsManagePage.waitForGridToLoad(null);
-
- dataJobsManagePage.chooseQuickFilter(0);
-
- // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
- dataJobsManagePage.filterByJobName(testJobsFixture[0].job_name.substring(0, 20));
-
- // verify url contains search value
- dataJobsManagePage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: '/manage/data-jobs',
- queryParams: {
- search: testJobsFixture[1].job_name,
- jobName: testJobsFixture[0].job_name.substring(0, 20),
- deploymentStatus: 'all'
- }
- });
-
- // verify 1 test row visible
- dataJobsManagePage.getDataGridCell(testJobsFixture[0].job_name).should('not.exist');
- dataJobsManagePage.getDataGridCell(testJobsFixture[1].job_name).scrollIntoView().should('be.visible');
-
- // clear search with button
- dataJobsManagePage.clearSearchFieldWithButton();
-
- // verify 2 test rows visible
- dataJobsManagePage.getDataGridCell(testJobsFixture[0].job_name).scrollIntoView().should('be.visible');
- dataJobsManagePage.getDataGridCell(testJobsFixture[1].job_name).scrollIntoView().should('be.visible');
-
- // verify url does not contain search value
- dataJobsManagePage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: '/manage/data-jobs',
- queryParams: {
- jobName: testJobsFixture[0].job_name.substring(0, 20),
- deploymentStatus: 'all'
- }
- });
- });
-
- it('refresh shows newly created job', () => {
- dataJobsManagePage = DataJobsManagePage.navigateTo();
-
- dataJobsManagePage.chooseQuickFilter(0);
-
- // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
- dataJobsManagePage.filterByJobName(testJobsFixture[0].job_name.substring(0, 20));
-
- dataJobsManagePage.getDataGridCell(testJobsFixture[0].job_name).should('have.text', testJobsFixture[0].job_name);
-
- dataJobsManagePage.getDataGridCell(additionalTestJobFixture.job_name).should('not.exist');
-
- DataJobsManagePage.createAdditionalShortLivedTestJobsNoDeploy();
-
- dataJobsManagePage.refreshDataGrid();
-
- dataJobsManagePage.getDataGridCell(additionalTestJobFixture.job_name).should('have.text', additionalTestJobFixture.job_name);
- });
-
- it('click on edit button opens new page with Job details', () => {
- dataJobsManagePage = DataJobsManagePage.navigateWithSideMenu();
-
- dataJobsManagePage.chooseQuickFilter(0);
-
- // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
- dataJobsManagePage.filterByJobName(testJobsFixture[0].job_name.substring(0, 20));
-
- dataJobsManagePage.openJobDetails(testJobsFixture[0].team, testJobsFixture[0].job_name);
-
- const dataJobManageDetailsPage = DataJobManageDetailsPage.getPage();
-
- dataJobManageDetailsPage.getPageTitle().scrollIntoView().should('be.visible').invoke('text').invoke('trim').should('eq', `Data Job: ${testJobsFixture[0].job_name}`);
-
- dataJobManageDetailsPage.getDescription().scrollIntoView().should('be.visible').should('contain.text', testJobsFixture[0].description.split(' ').slice(0, descriptionWordsBeforeTruncate).join(' '));
-
- dataJobManageDetailsPage.getSchedule().scrollIntoView().should('be.visible');
-
- dataJobManageDetailsPage.getDeploymentStatus('not-deployed').scrollIntoView().should('be.visible').should('have.text', 'Not Deployed');
- });
-
- it('quick filters', () => {
- // Disable data job before test start
- DataJobsManagePage.changeLongLivedJobStatus('failing', true)
- .then(() => DataJobsManagePage.changeShortLivedTestJobWithDeployStatus('v0', false))
- .then(() => {
- dataJobsManagePage = DataJobsManagePage.navigateTo();
-
- dataJobsManagePage.waitForClickThinkingTime();
- dataJobsManagePage.chooseQuickFilter(0);
-
- 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.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.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.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.changeShortLivedTestJobWithDeployStatus('v0', true);
- });
- });
-
- it('filter description data jobs', () => {
- dataJobsManagePage = DataJobsManagePage.navigateTo();
-
- dataJobsManagePage.chooseQuickFilter(0);
-
- // show panel for show/hide columns
- dataJobsManagePage.toggleColumnShowHidePanel();
-
- // verify column is not checked in toggling menu
- dataJobsManagePage.getDataGridColumnShowHideOption('Description').should('exist').should('not.be.checked');
-
- // verify header cell for column is not rendered
- dataJobsManagePage.getDataGridHeaderCell('Description').should('have.length', 0);
-
- // toggle column to render
- dataJobsManagePage.checkColumnShowHideOption('Description');
-
- // verify column is checked in toggling menu
- dataJobsManagePage.getHeaderColumnDescriptionName().should('exist');
-
- // filter by job description because
- dataJobsManagePage.filterByJobDescription('Test description 1');
-
- // verify url contains description value
- dataJobsManagePage.getCurrentUrl().should('match', new RegExp(`\\/manage\\/data-jobs\\?description=Test%20description%201&deploymentStatus=all$`));
-
- dataJobsManagePage.getDataGridCell(testJobsFixture[0].job_name).scrollIntoView().should('be.visible');
-
- dataJobsManagePage.getDataGridCell(testJobsFixture[1].job_name).should('not.exist');
- });
-
- it('perform filtering by description when URL contains description parameter', () => {
- // navigate with search value in URL
- dataJobsManagePage = DataJobsManagePage.navigateToDataJobUrl(`/manage/data-jobs?deploymentEnabled=enabled&description=Test%20description%201`);
-
- dataJobsManagePage.chooseQuickFilter(0);
- dataJobsManagePage.waitForGridToLoad(null);
-
- // show panel for show/hide columns
- dataJobsManagePage.toggleColumnShowHidePanel();
-
- // toggle column to render
- dataJobsManagePage.checkColumnShowHideOption('Description');
-
- // verify url contains search value
- dataJobsManagePage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: '/manage/data-jobs',
- queryParams: {
- deploymentStatus: 'all',
- description: 'Test%20description%201'
- }
- });
-
- // verify 1 test row visible
- dataJobsManagePage.getDataGridCell(testJobsFixture[0].job_name).scrollIntoView().should('be.visible');
-
- dataJobsManagePage.getDataGridCell(testJobsFixture[1].job_name).should('not.exist');
- });
-
- it('show/hide column when toggling from menu', () => {
- dataJobsManagePage = DataJobsManagePage.navigateTo();
-
- // show panel for show/hide columns
- dataJobsManagePage.toggleColumnShowHidePanel();
-
- // verify correct options are rendered
- dataJobsManagePage.getDataGridColumnShowHideOptionsValues().should('have.length', 11).invoke('join', ',').should('eq', 'Description,Deployment Status,Python Version,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('execute now', () => {
+ describe("extended", () => {
+ it("grid search parameter goes into URL", () => {
+ dataJobsManagePage = DataJobsManagePage.navigateTo();
+
+ dataJobsManagePage.chooseQuickFilter(0);
+
+ // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
+ dataJobsManagePage.filterByJobName(
+ testJobsFixture[0].job_name.substring(0, 20),
+ );
+
+ // verify 2 test rows visible
+ dataJobsManagePage
+ .getDataGridCell(testJobsFixture[0].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+ dataJobsManagePage
+ .getDataGridCell(testJobsFixture[1].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+
+ // do search
+ dataJobsManagePage.searchByJobName(testJobsFixture[0].job_name);
+
+ // verify 1 test row visible
+ dataJobsManagePage
+ .getDataGridCell(testJobsFixture[0].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+ dataJobsManagePage
+ .getDataGridCell(testJobsFixture[1].job_name)
+ .should("not.exist");
+
+ // verify url contains search value
+ dataJobsManagePage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: "/manage/data-jobs",
+ queryParams: {
+ search: testJobsFixture[0].job_name,
+ jobName: testJobsFixture[0].job_name.substring(0, 20),
+ deploymentStatus: "all",
+ },
+ });
+
+ // clear search with clear() method
+ dataJobsManagePage.clearSearchField();
+
+ // verify 2 test rows visible
+ dataJobsManagePage
+ .getDataGridCell(testJobsFixture[0].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+ dataJobsManagePage
+ .getDataGridCell(testJobsFixture[1].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+
+ // verify url does not contain search value
+ dataJobsManagePage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: "/manage/data-jobs",
+ queryParams: {
+ jobName: testJobsFixture[0].job_name.substring(0, 20),
+ deploymentStatus: "all",
+ },
+ });
+ });
+
+ it("grid search perform search when URL contains search parameter", () => {
+ // navigate with search value in URL
+ dataJobsManagePage = DataJobsManagePage.navigateToDataJobUrl(
+ `/manage/data-jobs?search=${testJobsFixture[1].job_name}`,
+ );
+
+ dataJobsManagePage.waitForGridToLoad(null);
+
+ dataJobsManagePage.chooseQuickFilter(0);
+
+ // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
+ dataJobsManagePage.filterByJobName(
+ testJobsFixture[0].job_name.substring(0, 20),
+ );
+
+ // verify url contains search value
+ dataJobsManagePage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: "/manage/data-jobs",
+ queryParams: {
+ search: testJobsFixture[1].job_name,
+ jobName: testJobsFixture[0].job_name.substring(0, 20),
+ deploymentStatus: "all",
+ },
+ });
+
+ // verify 1 test row visible
+ dataJobsManagePage
+ .getDataGridCell(testJobsFixture[0].job_name)
+ .should("not.exist");
+ dataJobsManagePage
+ .getDataGridCell(testJobsFixture[1].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+
+ // clear search with button
+ dataJobsManagePage.clearSearchFieldWithButton();
+
+ // verify 2 test rows visible
+ dataJobsManagePage
+ .getDataGridCell(testJobsFixture[0].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+ dataJobsManagePage
+ .getDataGridCell(testJobsFixture[1].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+
+ // verify url does not contain search value
+ dataJobsManagePage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: "/manage/data-jobs",
+ queryParams: {
+ jobName: testJobsFixture[0].job_name.substring(0, 20),
+ deploymentStatus: "all",
+ },
+ });
+ });
+
+ it("refresh shows newly created job", () => {
+ dataJobsManagePage = DataJobsManagePage.navigateTo();
+
+ dataJobsManagePage.chooseQuickFilter(0);
+
+ // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
+ dataJobsManagePage.filterByJobName(
+ testJobsFixture[0].job_name.substring(0, 20),
+ );
+
+ dataJobsManagePage
+ .getDataGridCell(testJobsFixture[0].job_name)
+ .should("have.text", testJobsFixture[0].job_name);
+
+ dataJobsManagePage
+ .getDataGridCell(additionalTestJobFixture.job_name)
+ .should("not.exist");
+
+ DataJobsManagePage.createAdditionalShortLivedTestJobsNoDeploy();
+
+ dataJobsManagePage.refreshDataGrid();
+
+ dataJobsManagePage
+ .getDataGridCell(additionalTestJobFixture.job_name)
+ .should("have.text", additionalTestJobFixture.job_name);
+ });
+
+ it("click on edit button opens new page with Job details", () => {
+ dataJobsManagePage = DataJobsManagePage.navigateWithSideMenu();
+
+ dataJobsManagePage.chooseQuickFilter(0);
+
+ // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
+ dataJobsManagePage.filterByJobName(
+ testJobsFixture[0].job_name.substring(0, 20),
+ );
+
+ dataJobsManagePage.openJobDetails(
+ testJobsFixture[0].team,
+ testJobsFixture[0].job_name,
+ );
+
+ const dataJobManageDetailsPage = DataJobManageDetailsPage.getPage();
+
+ dataJobManageDetailsPage
+ .getPageTitle()
+ .scrollIntoView()
+ .should("be.visible")
+ .invoke("text")
+ .invoke("trim")
+ .should("eq", `Data Job: ${testJobsFixture[0].job_name}`);
+
+ dataJobManageDetailsPage
+ .getDescription()
+ .scrollIntoView()
+ .should("be.visible")
+ .should(
+ "contain.text",
+ testJobsFixture[0].description
+ .split(" ")
+ .slice(0, descriptionWordsBeforeTruncate)
+ .join(" "),
+ );
+
+ dataJobManageDetailsPage
+ .getSchedule()
+ .scrollIntoView()
+ .should("be.visible");
+
+ dataJobManageDetailsPage
+ .getDeploymentStatus("not-deployed")
+ .scrollIntoView()
+ .should("be.visible")
+ .should("have.text", "Not Deployed");
+ });
+
+ it("quick filters", () => {
+ // Disable data job before test start
+ DataJobsManagePage.changeLongLivedJobStatus("failing", true)
+ .then(() =>
+ DataJobsManagePage.changeShortLivedTestJobWithDeployStatus(
+ "v0",
+ false,
+ ),
+ )
+ .then(() => {
dataJobsManagePage = DataJobsManagePage.navigateTo();
+ dataJobsManagePage.waitForClickThinkingTime();
dataJobsManagePage.chooseQuickFilter(0);
- // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
- dataJobsManagePage.filterByJobName(shortLivedTestJobWithDeployFixture.job_name.substring(0, 20));
-
- DataJobsManagePage.waitForShortLivedTestJobWithDeployExecutionToComplete('v0');
-
- dataJobsManagePage.executeDataJob(shortLivedTestJobWithDeployFixture.job_name);
-
- // 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(`execute now is disabled when Job doesn't have deployment`, () => {
- dataJobsManagePage = DataJobsManagePage.navigateTo();
-
- const jobName = testJobsFixture[0].job_name;
-
- dataJobsManagePage.chooseQuickFilter(0);
+ 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)",
+ ),
+ );
+ }
+ });
- // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
- dataJobsManagePage.filterByJobName(jobName.substring(0, 20));
+ dataJobsManagePage.waitForClickThinkingTime();
+ dataJobsManagePage.chooseQuickFilter(1);
+
+ dataJobsManagePage.getDataGridStatusIcons().then(($icons) => {
+ for (const icon of Array.from($icons)) {
+ cy.wrap(icon).should(
+ "have.attr",
+ "data-cy",
+ "data-pipelines-job-enabled",
+ );
+ }
+ });
- dataJobsManagePage.selectRow(jobName);
+ dataJobsManagePage.waitForClickThinkingTime();
+ dataJobsManagePage.chooseQuickFilter(2);
+
+ 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.getDataGridStatusIcons().then(($icons) => {
+ for (const icon of Array.from($icons)) {
+ cy.wrap(icon).should(
+ "have.attr",
+ "data-cy",
+ "data-pipelines-job-not-deployed",
+ );
+ }
+ });
- dataJobsManagePage.getExecuteNowGridButton().should('be.disabled');
- });
+ // Enable data job after job end
+ DataJobsManagePage.changeShortLivedTestJobWithDeployStatus(
+ "v0",
+ true,
+ );
+ });
+ });
+
+ it("filter description data jobs", () => {
+ dataJobsManagePage = DataJobsManagePage.navigateTo();
+
+ dataJobsManagePage.chooseQuickFilter(0);
+
+ // show panel for show/hide columns
+ dataJobsManagePage.toggleColumnShowHidePanel();
+
+ // verify column is not checked in toggling menu
+ dataJobsManagePage
+ .getDataGridColumnShowHideOption("Description")
+ .should("exist")
+ .should("not.be.checked");
+
+ // verify header cell for column is not rendered
+ dataJobsManagePage
+ .getDataGridHeaderCell("Description")
+ .should("have.length", 0);
+
+ // toggle column to render
+ dataJobsManagePage.checkColumnShowHideOption("Description");
+
+ // verify column is checked in toggling menu
+ dataJobsManagePage.getHeaderColumnDescriptionName().should("exist");
+
+ // filter by job description because
+ dataJobsManagePage.filterByJobDescription("Test description 1");
+
+ // verify url contains description value
+ dataJobsManagePage
+ .getCurrentUrl()
+ .should(
+ "match",
+ new RegExp(
+ `\\/manage\\/data-jobs\\?description=Test%20description%201&deploymentStatus=all$`,
+ ),
+ );
+
+ dataJobsManagePage
+ .getDataGridCell(testJobsFixture[0].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+
+ dataJobsManagePage
+ .getDataGridCell(testJobsFixture[1].job_name)
+ .should("not.exist");
+ });
+
+ it("perform filtering by description when URL contains description parameter", () => {
+ // navigate with search value in URL
+ dataJobsManagePage = DataJobsManagePage.navigateToDataJobUrl(
+ `/manage/data-jobs?deploymentEnabled=enabled&description=Test%20description%201`,
+ );
+
+ dataJobsManagePage.chooseQuickFilter(0);
+ dataJobsManagePage.waitForGridToLoad(null);
+
+ // show panel for show/hide columns
+ dataJobsManagePage.toggleColumnShowHidePanel();
+
+ // toggle column to render
+ dataJobsManagePage.checkColumnShowHideOption("Description");
+
+ // verify url contains search value
+ dataJobsManagePage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: "/manage/data-jobs",
+ queryParams: {
+ deploymentStatus: "all",
+ description: "Test%20description%201",
+ },
+ });
+
+ // verify 1 test row visible
+ dataJobsManagePage
+ .getDataGridCell(testJobsFixture[0].job_name)
+ .scrollIntoView()
+ .should("be.visible");
+
+ dataJobsManagePage
+ .getDataGridCell(testJobsFixture[1].job_name)
+ .should("not.exist");
+ });
+
+ it("show/hide column when toggling from menu", () => {
+ dataJobsManagePage = DataJobsManagePage.navigateTo();
+
+ // show panel for show/hide columns
+ dataJobsManagePage.toggleColumnShowHidePanel();
+
+ // verify correct options are rendered
+ dataJobsManagePage
+ .getDataGridColumnShowHideOptionsValues()
+ .should("have.length", 11)
+ .invoke("join", ",")
+ .should(
+ "eq",
+ "Description,Deployment Status,Python Version,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("execute now", () => {
+ dataJobsManagePage = DataJobsManagePage.navigateTo();
+
+ dataJobsManagePage.chooseQuickFilter(0);
+
+ // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
+ dataJobsManagePage.filterByJobName(
+ shortLivedTestJobWithDeployFixture.job_name.substring(0, 20),
+ );
+
+ DataJobsManagePage.waitForShortLivedTestJobWithDeployExecutionToComplete(
+ "v0",
+ );
+
+ dataJobsManagePage.executeDataJob(
+ shortLivedTestJobWithDeployFixture.job_name,
+ );
+
+ // 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(`execute now is disabled when Job doesn't have deployment`, () => {
+ dataJobsManagePage = DataJobsManagePage.navigateTo();
+
+ const jobName = testJobsFixture[0].job_name;
+
+ dataJobsManagePage.chooseQuickFilter(0);
+
+ // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
+ dataJobsManagePage.filterByJobName(jobName.substring(0, 20));
+
+ dataJobsManagePage.selectRow(jobName);
+
+ dataJobsManagePage.waitForClickThinkingTime();
+
+ dataJobsManagePage.getExecuteNowGridButton().should("be.disabled");
+ });
});
-});
+ },
+);
diff --git a/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/manage/data-jobs/details/data-job-details.spec.js b/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/manage/data-jobs/details/data-job-details.spec.js
index e7a46c66f5..5ce59528ea 100644
--- a/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/manage/data-jobs/details/data-job-details.spec.js
+++ b/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/manage/data-jobs/details/data-job-details.spec.js
@@ -5,12 +5,15 @@
///
-import { compareDatesASC } from '../../../../../plugins/helpers/job-helpers.plugins';
+import { compareDatesASC } from "../../../../../plugins/helpers/job-helpers.plugins";
-import { DataJobsManagePage } from '../../../../../support/pages/manage/data-jobs/data-jobs.po';
-import { DataJobManageDetailsPage } from '../../../../../support/pages/manage/data-jobs/details/data-job-details.po';
+import { DataJobsManagePage } from "../../../../../support/pages/manage/data-jobs/data-jobs.po";
+import { DataJobManageDetailsPage } from "../../../../../support/pages/manage/data-jobs/details/data-job-details.po";
-describe('Data Job Manage Details Page', { tags: ['@dataPipelines', '@manageDataJobDetails', '@manage'] }, () => {
+describe(
+ "Data Job Manage Details Page",
+ { tags: ["@dataPipelines", "@manageDataJobDetails", "@manage"] },
+ () => {
const descriptionWordsBeforeTruncate = 12;
/**
@@ -35,202 +38,300 @@ describe('Data Job Manage Details Page', { tags: ['@dataPipelines', '@manageData
let longLivedFailingJobFixture;
before(() => {
- return DataJobManageDetailsPage.recordHarIfSupported()
- .then(() => cy.clearLocalStorageSnapshot('data-job-manage-details'))
- .then(() => DataJobManageDetailsPage.login())
- .then(() => cy.saveLocalStorage('data-job-manage-details'))
- .then(() => DataJobManageDetailsPage.deleteShortLivedTestJobsNoDeploy(true))
- .then(() => DataJobManageDetailsPage.createLongLivedJobs('failing'))
- .then(() =>
- DataJobManageDetailsPage.provideExecutionsForLongLivedJobs({
- job: 'failing'
- })
- )
- .then(() =>
- DataJobManageDetailsPage.loadLongLivedFailingJobFixture().then((loadedTestJob) => {
- longLivedFailingJobFixture = loadedTestJob;
-
- return cy.wrap({
- context: 'manage::1::data-job-details.spec::before()',
- action: 'continue'
- });
- })
- )
- .then(() => DataJobManageDetailsPage.createShortLivedTestJobWithDeploy('v1'))
- .then(() =>
- DataJobManageDetailsPage.loadShortLivedTestJobFixtureWithDeploy('v1').then((loadedTestJob) => {
- shortLivedTestJobWithDeployFixture = loadedTestJob;
-
- return cy.wrap({
- context: 'manage::2::data-job-details.spec::before()',
- action: 'continue'
- });
- })
- )
- .then(() => DataJobManageDetailsPage.createShortLivedTestJobsNoDeploy())
- .then(() =>
- DataJobManageDetailsPage.loadShortLivedTestJobsFixtureNoDeploy().then((fixtures) => {
- testJobsFixture = [fixtures[0], fixtures[1]];
- additionalTestJobFixture = fixtures[2];
-
- return cy.wrap({
- context: 'manage::3::data-job-details.spec::before()',
- action: 'continue'
- });
- })
- );
+ return DataJobManageDetailsPage.recordHarIfSupported()
+ .then(() => cy.clearLocalStorageSnapshot("data-job-manage-details"))
+ .then(() => DataJobManageDetailsPage.login())
+ .then(() => cy.saveLocalStorage("data-job-manage-details"))
+ .then(() =>
+ DataJobManageDetailsPage.deleteShortLivedTestJobsNoDeploy(true),
+ )
+ .then(() => DataJobManageDetailsPage.createLongLivedJobs("failing"))
+ .then(() =>
+ DataJobManageDetailsPage.provideExecutionsForLongLivedJobs({
+ job: "failing",
+ }),
+ )
+ .then(() =>
+ DataJobManageDetailsPage.loadLongLivedFailingJobFixture().then(
+ (loadedTestJob) => {
+ longLivedFailingJobFixture = loadedTestJob;
+
+ return cy.wrap({
+ context: "manage::1::data-job-details.spec::before()",
+ action: "continue",
+ });
+ },
+ ),
+ )
+ .then(() =>
+ DataJobManageDetailsPage.createShortLivedTestJobWithDeploy("v1"),
+ )
+ .then(() =>
+ DataJobManageDetailsPage.loadShortLivedTestJobFixtureWithDeploy(
+ "v1",
+ ).then((loadedTestJob) => {
+ shortLivedTestJobWithDeployFixture = loadedTestJob;
+
+ return cy.wrap({
+ context: "manage::2::data-job-details.spec::before()",
+ action: "continue",
+ });
+ }),
+ )
+ .then(() => DataJobManageDetailsPage.createShortLivedTestJobsNoDeploy())
+ .then(() =>
+ DataJobManageDetailsPage.loadShortLivedTestJobsFixtureNoDeploy().then(
+ (fixtures) => {
+ testJobsFixture = [fixtures[0], fixtures[1]];
+ additionalTestJobFixture = fixtures[2];
+
+ return cy.wrap({
+ context: "manage::3::data-job-details.spec::before()",
+ action: "continue",
+ });
+ },
+ ),
+ );
});
after(() => {
- DataJobManageDetailsPage.deleteShortLivedTestJobWithDeploy('v1');
- DataJobManageDetailsPage.deleteShortLivedTestJobsNoDeploy();
+ DataJobManageDetailsPage.deleteShortLivedTestJobWithDeploy("v1");
+ DataJobManageDetailsPage.deleteShortLivedTestJobsNoDeploy();
- DataJobManageDetailsPage.saveHarIfSupported();
+ DataJobManageDetailsPage.saveHarIfSupported();
});
beforeEach(() => {
- cy.restoreLocalStorage('data-job-manage-details');
+ cy.restoreLocalStorage("data-job-manage-details");
- DataJobManageDetailsPage.wireUserSession();
- DataJobManageDetailsPage.initInterceptors();
+ DataJobManageDetailsPage.wireUserSession();
+ DataJobManageDetailsPage.initInterceptors();
});
- describe('smoke', { tags: ['@smoke'] }, () => {
- it('should verify will open job details', () => {
- const dataJobsManagePage = DataJobsManagePage.navigateWithSideMenu();
-
- dataJobsManagePage.chooseQuickFilter(0);
-
- // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
- dataJobsManagePage.filterByJobName(shortLivedTestJobWithDeployFixture.job_name.substring(0, 20));
-
- dataJobsManagePage.openJobDetails(shortLivedTestJobWithDeployFixture.team, shortLivedTestJobWithDeployFixture.job_name);
-
- dataJobManageDetailsPage = DataJobManageDetailsPage.getPage();
-
- dataJobManageDetailsPage.getPageTitle().invoke('text').invoke('trim').should('eq', `Data Job: ${shortLivedTestJobWithDeployFixture.job_name}`);
- });
-
- it('disable/enable job', () => {
- dataJobManageDetailsPage = DataJobManageDetailsPage.navigateTo(shortLivedTestJobWithDeployFixture.team, shortLivedTestJobWithDeployFixture.job_name);
-
- //Toggle job status twice, enable to disable and vice versa.
- dataJobManageDetailsPage.toggleJobStatus(shortLivedTestJobWithDeployFixture.job_name);
- dataJobManageDetailsPage.toggleJobStatus(shortLivedTestJobWithDeployFixture.job_name);
- });
-
- it('execute now', () => {
- dataJobManageDetailsPage = DataJobManageDetailsPage.navigateTo(shortLivedTestJobWithDeployFixture.team, shortLivedTestJobWithDeployFixture.job_name);
-
- DataJobManageDetailsPage.waitForShortLivedTestJobWithDeployExecutionToComplete('v1');
-
- dataJobManageDetailsPage.executeNow();
-
- dataJobManageDetailsPage
- .getToastTitle(10000)
- .should('exist')
- .contains(/Data job Queued for execution|Failed, Data job is already executing/);
- });
-
- it('delete job', () => {
- DataJobsManagePage.createAdditionalShortLivedTestJobsNoDeploy();
-
- dataJobManageDetailsPage = DataJobManageDetailsPage.navigateTo(additionalTestJobFixture.team, additionalTestJobFixture.job_name);
-
- dataJobManageDetailsPage.openActionDropdown();
-
- dataJobManageDetailsPage.deleteJob();
-
- dataJobManageDetailsPage
- .getToastTitle(20000) // Wait up to 20 seconds for the job to be deleted.
- .should('contain.text', 'Data job delete completed');
-
- const dataJobsManagePage = DataJobsManagePage.getPage();
-
- dataJobsManagePage.waitForGridDataLoad();
-
- dataJobsManagePage.chooseQuickFilter(0);
-
- dataJobsManagePage
- .getDataGridCell(additionalTestJobFixture.job_name, 10000) // Wait up to 10 seconds for the jobs list to show.
- .should('not.exist');
- });
+ describe("smoke", { tags: ["@smoke"] }, () => {
+ it("should verify will open job details", () => {
+ const dataJobsManagePage = DataJobsManagePage.navigateWithSideMenu();
+
+ dataJobsManagePage.chooseQuickFilter(0);
+
+ // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
+ dataJobsManagePage.filterByJobName(
+ shortLivedTestJobWithDeployFixture.job_name.substring(0, 20),
+ );
+
+ dataJobsManagePage.openJobDetails(
+ shortLivedTestJobWithDeployFixture.team,
+ shortLivedTestJobWithDeployFixture.job_name,
+ );
+
+ dataJobManageDetailsPage = DataJobManageDetailsPage.getPage();
+
+ dataJobManageDetailsPage
+ .getPageTitle()
+ .invoke("text")
+ .invoke("trim")
+ .should(
+ "eq",
+ `Data Job: ${shortLivedTestJobWithDeployFixture.job_name}`,
+ );
+ });
+
+ it("disable/enable job", () => {
+ dataJobManageDetailsPage = DataJobManageDetailsPage.navigateTo(
+ shortLivedTestJobWithDeployFixture.team,
+ shortLivedTestJobWithDeployFixture.job_name,
+ );
+
+ //Toggle job status twice, enable to disable and vice versa.
+ dataJobManageDetailsPage.toggleJobStatus(
+ shortLivedTestJobWithDeployFixture.job_name,
+ );
+ dataJobManageDetailsPage.toggleJobStatus(
+ shortLivedTestJobWithDeployFixture.job_name,
+ );
+ });
+
+ it("execute now", () => {
+ dataJobManageDetailsPage = DataJobManageDetailsPage.navigateTo(
+ shortLivedTestJobWithDeployFixture.team,
+ shortLivedTestJobWithDeployFixture.job_name,
+ );
+
+ DataJobManageDetailsPage.waitForShortLivedTestJobWithDeployExecutionToComplete(
+ "v1",
+ );
+
+ dataJobManageDetailsPage.executeNow();
+
+ dataJobManageDetailsPage
+ .getToastTitle(10000)
+ .should("exist")
+ .contains(
+ /Data job Queued for execution|Failed, Data job is already executing/,
+ );
+ });
+
+ it("delete job", () => {
+ DataJobsManagePage.createAdditionalShortLivedTestJobsNoDeploy();
+
+ dataJobManageDetailsPage = DataJobManageDetailsPage.navigateTo(
+ additionalTestJobFixture.team,
+ additionalTestJobFixture.job_name,
+ );
+
+ dataJobManageDetailsPage.openActionDropdown();
+
+ dataJobManageDetailsPage.deleteJob();
+
+ dataJobManageDetailsPage
+ .getToastTitle(20000) // Wait up to 20 seconds for the job to be deleted.
+ .should("contain.text", "Data job delete completed");
+
+ const dataJobsManagePage = DataJobsManagePage.getPage();
+
+ dataJobsManagePage.waitForGridDataLoad();
+
+ dataJobsManagePage.chooseQuickFilter(0);
+
+ dataJobsManagePage
+ .getDataGridCell(additionalTestJobFixture.job_name, 10000) // Wait up to 10 seconds for the jobs list to show.
+ .should("not.exist");
+ });
});
- describe('extended', () => {
- it('edit job description', () => {
- let newDescription = 'Test if changing the description is working';
-
- const dataJobsManagePage = DataJobsManagePage.navigateWithSideMenu();
-
- dataJobsManagePage.chooseQuickFilter(0);
+ describe("extended", () => {
+ it("edit job description", () => {
+ let newDescription = "Test if changing the description is working";
+
+ const dataJobsManagePage = DataJobsManagePage.navigateWithSideMenu();
+
+ dataJobsManagePage.chooseQuickFilter(0);
+
+ // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
+ dataJobsManagePage.filterByJobName(
+ testJobsFixture[0].job_name.substring(0, 20),
+ );
+
+ dataJobsManagePage.openJobDetails(
+ testJobsFixture[0].team,
+ testJobsFixture[0].job_name,
+ );
+
+ dataJobManageDetailsPage = DataJobManageDetailsPage.getPage();
+
+ dataJobManageDetailsPage.openDescription();
+
+ dataJobManageDetailsPage.enterDescriptionDetails(newDescription);
+
+ dataJobManageDetailsPage.saveDescription();
+
+ dataJobManageDetailsPage
+ .getDescription()
+ .scrollIntoView()
+ .should("be.visible")
+ .should(
+ "contain.text",
+ newDescription
+ .split(" ")
+ .slice(0, descriptionWordsBeforeTruncate)
+ .join(" "),
+ );
+ });
+
+ it("download job key", () => {
+ dataJobManageDetailsPage = DataJobManageDetailsPage.navigateTo(
+ shortLivedTestJobWithDeployFixture.team,
+ shortLivedTestJobWithDeployFixture.job_name,
+ );
+
+ dataJobManageDetailsPage.openActionDropdown();
+
+ dataJobManageDetailsPage.downloadJobKey();
+
+ dataJobManageDetailsPage
+ .readFile(
+ "downloadsFolder",
+ `${shortLivedTestJobWithDeployFixture.job_name}.keytab`,
+ )
+ .should("exist");
+ });
+
+ it("executions timeline", () => {
+ const jobName = longLivedFailingJobFixture.job_name;
+ const teamName = longLivedFailingJobFixture.team;
+
+ dataJobManageDetailsPage = DataJobManageDetailsPage.navigateTo(
+ teamName,
+ jobName,
+ );
+
+ dataJobManageDetailsPage
+ .waitForGetExecutionsReqInterceptor()
+ .then((interception) => {
+ const executionsResponse = [];
+ const content = interception?.response?.body?.data?.content;
+
+ if (content) {
+ executionsResponse.push(...content);
+ }
+
+ const lastExecutions = executionsResponse
+ .sort((left, right) => compareDatesASC(left, right))
+ .slice(
+ executionsResponse.length > 5
+ ? executionsResponse.length - 5
+ : 0,
+ );
+
+ const lastExecutionsSize = lastExecutions.length;
+ const lastExecution = lastExecutions[lastExecutionsSize - 1];
+ const timelineSize = lastExecutionsSize + 1; // +1 next execution
- // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
- dataJobsManagePage.filterByJobName(testJobsFixture[0].job_name.substring(0, 20));
-
- dataJobsManagePage.openJobDetails(testJobsFixture[0].team, testJobsFixture[0].job_name);
-
- dataJobManageDetailsPage = DataJobManageDetailsPage.getPage();
-
- dataJobManageDetailsPage.openDescription();
-
- dataJobManageDetailsPage.enterDescriptionDetails(newDescription);
-
- dataJobManageDetailsPage.saveDescription();
-
- dataJobManageDetailsPage.getDescription().scrollIntoView().should('be.visible').should('contain.text', newDescription.split(' ').slice(0, descriptionWordsBeforeTruncate).join(' '));
- });
-
- it('download job key', () => {
- dataJobManageDetailsPage = DataJobManageDetailsPage.navigateTo(shortLivedTestJobWithDeployFixture.team, shortLivedTestJobWithDeployFixture.job_name);
-
- dataJobManageDetailsPage.openActionDropdown();
-
- dataJobManageDetailsPage.downloadJobKey();
-
- dataJobManageDetailsPage.readFile('downloadsFolder', `${shortLivedTestJobWithDeployFixture.job_name}.keytab`).should('exist');
- });
-
- it('executions timeline', () => {
- const jobName = longLivedFailingJobFixture.job_name;
- const teamName = longLivedFailingJobFixture.team;
-
- dataJobManageDetailsPage = DataJobManageDetailsPage.navigateTo(teamName, jobName);
-
- dataJobManageDetailsPage.waitForGetExecutionsReqInterceptor().then((interception) => {
- const executionsResponse = [];
- const content = interception?.response?.body?.data?.content;
-
- if (content) {
- executionsResponse.push(...content);
- }
-
- const lastExecutions = executionsResponse.sort((left, right) => compareDatesASC(left, right)).slice(executionsResponse.length > 5 ? executionsResponse.length - 5 : 0);
-
- const lastExecutionsSize = lastExecutions.length;
- const lastExecution = lastExecutions[lastExecutionsSize - 1];
- const timelineSize = lastExecutionsSize + 1; // +1 next execution
-
- dataJobManageDetailsPage.getExecutionsSteps().should('have.length', timelineSize);
-
- for (const execution of lastExecutions) {
- const executionTimelineSelector = `[data-cy=${execution.id}]`;
-
- const executionStartedTime = dataJobManageDetailsPage.formatDateTimeFromISOToExecutionsTimeline(execution.startTime);
- dataJobManageDetailsPage.getExecutionStepStartedTile(executionTimelineSelector).invoke('trim').should('eq', `Started ${executionStartedTime}`);
-
- if (execution?.type?.toLowerCase() === 'manual') {
- dataJobManageDetailsPage.getExecutionStepManualTriggerer(executionTimelineSelector).should('be.visible');
- }
-
- if (execution?.status?.toLowerCase() !== 'running' && execution?.status?.toLowerCase() !== 'submitted') {
- dataJobManageDetailsPage.getExecutionStepStatusIcon(executionTimelineSelector, execution.status).should('exist');
-
- const executionEndTime = dataJobManageDetailsPage.formatDateTimeFromISOToExecutionsTimeline(execution.endTime);
- dataJobManageDetailsPage.getExecutionStepEndedTile(executionTimelineSelector).invoke('trim').should('eq', `Ended ${executionEndTime}`);
- }
- }
- });
- });
+ dataJobManageDetailsPage
+ .getExecutionsSteps()
+ .should("have.length", timelineSize);
+
+ for (const execution of lastExecutions) {
+ const executionTimelineSelector = `[data-cy=${execution.id}]`;
+
+ const executionStartedTime =
+ dataJobManageDetailsPage.formatDateTimeFromISOToExecutionsTimeline(
+ execution.startTime,
+ );
+ dataJobManageDetailsPage
+ .getExecutionStepStartedTile(executionTimelineSelector)
+ .invoke("trim")
+ .should("eq", `Started ${executionStartedTime}`);
+
+ if (execution?.type?.toLowerCase() === "manual") {
+ dataJobManageDetailsPage
+ .getExecutionStepManualTriggerer(executionTimelineSelector)
+ .should("be.visible");
+ }
+
+ if (
+ execution?.status?.toLowerCase() !== "running" &&
+ execution?.status?.toLowerCase() !== "submitted"
+ ) {
+ dataJobManageDetailsPage
+ .getExecutionStepStatusIcon(
+ executionTimelineSelector,
+ execution.status,
+ )
+ .should("exist");
+
+ const executionEndTime =
+ dataJobManageDetailsPage.formatDateTimeFromISOToExecutionsTimeline(
+ execution.endTime,
+ );
+ dataJobManageDetailsPage
+ .getExecutionStepEndedTile(executionTimelineSelector)
+ .invoke("trim")
+ .should("eq", `Ended ${executionEndTime}`);
+ }
+ }
+ });
+ });
});
-});
+ },
+);
diff --git a/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/manage/data-jobs/executions/data-job-executions.spec.js b/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/manage/data-jobs/executions/data-job-executions.spec.js
index 9bc2f3ad3e..fe711df78a 100644
--- a/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/manage/data-jobs/executions/data-job-executions.spec.js
+++ b/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/manage/data-jobs/executions/data-job-executions.spec.js
@@ -5,10 +5,13 @@
///
-import { DataJobsManagePage } from '../../../../../support/pages/manage/data-jobs/data-jobs.po';
-import { DataJobManageExecutionsPage } from '../../../../../support/pages/manage/data-jobs/executions/data-job-executions.po';
+import { DataJobsManagePage } from "../../../../../support/pages/manage/data-jobs/data-jobs.po";
+import { DataJobManageExecutionsPage } from "../../../../../support/pages/manage/data-jobs/executions/data-job-executions.po";
-describe('Data Job Manage Executions Page', { tags: ['@dataPipelines', '@manageDataJobExecutions', '@manage'] }, () => {
+describe(
+ "Data Job Manage Executions Page",
+ { tags: ["@dataPipelines", "@manageDataJobExecutions", "@manage"] },
+ () => {
/**
* @type {{job_name:string; description:string; team:string; config:{db_default_type:string; contacts:{}; schedule:{schedule_cron:string}; generate_keytab:boolean; enable_execution_notifications:boolean}}}
*/
@@ -19,1664 +22,1985 @@ describe('Data Job Manage Executions Page', { tags: ['@dataPipelines', '@manageD
let longLivedFailingJobFixture;
before(() => {
- return DataJobManageExecutionsPage.recordHarIfSupported()
- .then(() => cy.clearLocalStorageSnapshot('data-job-manage-executions'))
- .then(() => DataJobManageExecutionsPage.login())
- .then(() => cy.saveLocalStorage('data-job-manage-executions'))
- .then(() => DataJobManageExecutionsPage.createLongLivedJobs('failing'))
- .then(() => DataJobManageExecutionsPage.provideExecutionsForLongLivedJobs({ job: 'failing', executions: 3 }))
- .then(() =>
- DataJobManageExecutionsPage.loadLongLivedFailingJobFixture().then((loadedTestJob) => {
- longLivedFailingJobFixture = loadedTestJob;
-
- return cy.wrap({
- context: 'manage::1::data-job-executions.spec::before()',
- action: 'continue'
- });
- })
- )
- .then(() => DataJobManageExecutionsPage.createShortLivedTestJobWithDeploy('v2'))
- .then(() => DataJobManageExecutionsPage.provideExecutionsForShortLivedTestJobWithDeploy('v2'))
- .then(() =>
- DataJobManageExecutionsPage.loadShortLivedTestJobFixtureWithDeploy('v2').then((loadedTestJob) => {
- shortLivedTestJobWithDeployFixture = loadedTestJob;
-
- return cy.wrap({
- context: 'manage::2::data-job-executions.spec::before()',
- action: 'continue'
- });
- })
- );
+ return DataJobManageExecutionsPage.recordHarIfSupported()
+ .then(() => cy.clearLocalStorageSnapshot("data-job-manage-executions"))
+ .then(() => DataJobManageExecutionsPage.login())
+ .then(() => cy.saveLocalStorage("data-job-manage-executions"))
+ .then(() => DataJobManageExecutionsPage.createLongLivedJobs("failing"))
+ .then(() =>
+ DataJobManageExecutionsPage.provideExecutionsForLongLivedJobs({
+ job: "failing",
+ executions: 3,
+ }),
+ )
+ .then(() =>
+ DataJobManageExecutionsPage.loadLongLivedFailingJobFixture().then(
+ (loadedTestJob) => {
+ longLivedFailingJobFixture = loadedTestJob;
+
+ return cy.wrap({
+ context: "manage::1::data-job-executions.spec::before()",
+ action: "continue",
+ });
+ },
+ ),
+ )
+ .then(() =>
+ DataJobManageExecutionsPage.createShortLivedTestJobWithDeploy("v2"),
+ )
+ .then(() =>
+ DataJobManageExecutionsPage.provideExecutionsForShortLivedTestJobWithDeploy(
+ "v2",
+ ),
+ )
+ .then(() =>
+ DataJobManageExecutionsPage.loadShortLivedTestJobFixtureWithDeploy(
+ "v2",
+ ).then((loadedTestJob) => {
+ shortLivedTestJobWithDeployFixture = loadedTestJob;
+
+ return cy.wrap({
+ context: "manage::2::data-job-executions.spec::before()",
+ action: "continue",
+ });
+ }),
+ );
});
after(() => {
- DataJobManageExecutionsPage.deleteShortLivedTestJobWithDeploy('v2');
+ DataJobManageExecutionsPage.deleteShortLivedTestJobWithDeploy("v2");
- DataJobManageExecutionsPage.saveHarIfSupported();
+ DataJobManageExecutionsPage.saveHarIfSupported();
});
beforeEach(() => {
- cy.restoreLocalStorage('data-job-manage-executions');
+ cy.restoreLocalStorage("data-job-manage-executions");
- DataJobManageExecutionsPage.wireUserSession();
- DataJobManageExecutionsPage.initInterceptors();
+ DataJobManageExecutionsPage.wireUserSession();
+ DataJobManageExecutionsPage.initInterceptors();
});
- describe('smoke', { tags: ['@smoke'] }, () => {
- it(`should open Details and verify Executions tab is displayed and navigates`, () => {
- cy.log('Fixture for name: ' + longLivedFailingJobFixture.job_name);
+ describe("smoke", { tags: ["@smoke"] }, () => {
+ it(`should open Details and verify Executions tab is displayed and navigates`, () => {
+ cy.log("Fixture for name: " + longLivedFailingJobFixture.job_name);
- const dataJobsManagePage = DataJobsManagePage.navigateWithSideMenu();
+ const dataJobsManagePage = DataJobsManagePage.navigateWithSideMenu();
- dataJobsManagePage.chooseQuickFilter(0);
+ dataJobsManagePage.chooseQuickFilter(0);
- // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
- dataJobsManagePage.filterByJobName(longLivedFailingJobFixture.job_name.substring(0, 20));
+ // filter by job name substring because there are a lot of jobs, and it could potentially be on second/third page
+ dataJobsManagePage.filterByJobName(
+ longLivedFailingJobFixture.job_name.substring(0, 20),
+ );
- dataJobsManagePage.openJobDetails(longLivedFailingJobFixture.team, longLivedFailingJobFixture.job_name);
+ dataJobsManagePage.openJobDetails(
+ longLivedFailingJobFixture.team,
+ longLivedFailingJobFixture.job_name,
+ );
- const dataJobManageExecutionsPage = DataJobManageExecutionsPage.getPage();
+ const dataJobManageExecutionsPage =
+ DataJobManageExecutionsPage.getPage();
- dataJobManageExecutionsPage.getDetailsTab().should('exist').should('have.class', 'active');
+ dataJobManageExecutionsPage
+ .getDetailsTab()
+ .should("exist")
+ .should("have.class", "active");
- dataJobManageExecutionsPage.getExecutionsTab().should('exist').should('not.have.class', 'active');
+ dataJobManageExecutionsPage
+ .getExecutionsTab()
+ .should("exist")
+ .should("not.have.class", "active");
- dataJobManageExecutionsPage.openExecutionsTab();
+ dataJobManageExecutionsPage.openExecutionsTab();
- const dataJobExecutionsPage = DataJobManageExecutionsPage.getPage();
+ const dataJobExecutionsPage = DataJobManageExecutionsPage.getPage();
- dataJobExecutionsPage.getDetailsTab().should('exist').should('not.have.class', 'active');
+ dataJobExecutionsPage
+ .getDetailsTab()
+ .should("exist")
+ .should("not.have.class", "active");
- dataJobExecutionsPage.getExecutionsTab().should('exist').should('have.class', 'active');
+ dataJobExecutionsPage
+ .getExecutionsTab()
+ .should("exist")
+ .should("have.class", "active");
- dataJobExecutionsPage.getDataGrid().should('exist');
- });
+ dataJobExecutionsPage.getDataGrid().should("exist");
+ });
+
+ it("should verify elements are rendered in DOM", () => {
+ const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(
+ longLivedFailingJobFixture.team,
+ longLivedFailingJobFixture.job_name,
+ );
+
+ dataJobExecutionsPage
+ .getPageTitle()
+ .scrollIntoView()
+ .should("be.visible")
+ .should("contains.text", longLivedFailingJobFixture.job_name);
+
+ dataJobExecutionsPage
+ .getDetailsTab()
+ .should("exist")
+ .should("not.have.class", "active");
+
+ dataJobExecutionsPage
+ .getExecutionsTab()
+ .should("exist")
+ .should("have.class", "active");
+
+ dataJobExecutionsPage.getExecuteOrCancelButton().should("exist");
+
+ dataJobExecutionsPage.getActionDropdownBtn().should("exist");
+
+ dataJobExecutionsPage.openActionDropdown();
+
+ dataJobExecutionsPage.getDeleteJobBtn().should("exist");
- it('should verify elements are rendered in DOM', () => {
- const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(longLivedFailingJobFixture.team, longLivedFailingJobFixture.job_name);
+ dataJobExecutionsPage.clickOnContentContainer();
- dataJobExecutionsPage.getPageTitle().scrollIntoView().should('be.visible').should('contains.text', longLivedFailingJobFixture.job_name);
+ dataJobExecutionsPage.waitForSmartDelay();
- dataJobExecutionsPage.getDetailsTab().should('exist').should('not.have.class', 'active');
+ dataJobExecutionsPage.getTimePeriod().should("exist");
- dataJobExecutionsPage.getExecutionsTab().should('exist').should('have.class', 'active');
+ dataJobExecutionsPage.getStatusChart().should("exist");
- dataJobExecutionsPage.getExecuteOrCancelButton().should('exist');
+ dataJobExecutionsPage.getDurationChart().should("exist");
- dataJobExecutionsPage.getActionDropdownBtn().should('exist');
+ dataJobExecutionsPage.getDataGrid().should("exist");
- dataJobExecutionsPage.openActionDropdown();
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+ });
- dataJobExecutionsPage.getDeleteJobBtn().should('exist');
+ it("should verify start then cancel execution works", () => {
+ const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(
+ shortLivedTestJobWithDeployFixture.team,
+ shortLivedTestJobWithDeployFixture.job_name,
+ );
- dataJobExecutionsPage.clickOnContentContainer();
+ DataJobManageExecutionsPage.waitForDataJobToNotHaveRunningExecution();
- dataJobExecutionsPage.waitForSmartDelay();
+ dataJobExecutionsPage
+ .getExecutionsTab()
+ .should("exist")
+ .should("have.class", "active");
- dataJobExecutionsPage.getTimePeriod().should('exist');
+ // Execute data job and check if the execution status after that is Running or Submitted
+ dataJobExecutionsPage.executeNow(true);
+ dataJobExecutionsPage
+ .getExecutionStatus()
+ .first()
+ .contains(/Running|Submitted/);
- dataJobExecutionsPage.getStatusChart().should('exist');
+ // Cancel data job execution and check if the status after that is Cancelled
+ dataJobExecutionsPage.cancelExecution(true);
+ dataJobExecutionsPage
+ .getExecutionStatus()
+ .first()
+ .should("contains.text", "Canceled");
+ });
+ });
- dataJobExecutionsPage.getDurationChart().should('exist');
+ describe("extended", () => {
+ it("should verify on URL navigate to Executions will open the page", () => {
+ const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(
+ longLivedFailingJobFixture.team,
+ longLivedFailingJobFixture.job_name,
+ );
+
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ },
+ });
+
+ dataJobExecutionsPage
+ .getDetailsTab()
+ .should("exist")
+ .should("not.have.class", "active");
+
+ dataJobExecutionsPage
+ .getExecutionsTab()
+ .should("exist")
+ .should("have.class", "active");
+
+ dataJobExecutionsPage.getDataGrid().should("exist");
+ });
+
+ it("should verify time period is in correct format", () => {
+ const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(
+ longLivedFailingJobFixture.team,
+ longLivedFailingJobFixture.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("should verify refresh button will show spinner and then load data", () => {
+ const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(
+ longLivedFailingJobFixture.team,
+ longLivedFailingJobFixture.job_name,
+ );
+
+ // verify before
+ dataJobExecutionsPage.getDataGrid().should("exist");
+ dataJobExecutionsPage.getExecLoadingSpinner().should("not.exist");
+ dataJobExecutionsPage.getDataGridSpinner().should("not.exist");
+
+ // trigger refresh
+ dataJobExecutionsPage.waitForActionThinkingTime();
+ dataJobExecutionsPage.refreshExecData();
+
+ // verify while refreshing
+ dataJobExecutionsPage.getDataGrid().should("exist");
+ dataJobExecutionsPage.getExecLoadingSpinner().should("exist");
+ dataJobExecutionsPage.getDataGridSpinner().should("exist");
+
+ // wait loading data to finish
+ dataJobExecutionsPage.waitForGridDataLoad();
+
+ // verify after refresh
+ dataJobExecutionsPage.getDataGrid().should("exist");
+ dataJobExecutionsPage.getExecLoadingSpinner().should("not.exist");
+ dataJobExecutionsPage.getDataGridSpinner().should("not.exist");
+ });
+
+ describe("DataGrid Filters", () => {
+ it("should verify status filter options are rendered and behaves correctly", () => {
+ const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(
+ longLivedFailingJobFixture.team,
+ longLivedFailingJobFixture.job_name,
+ );
+
+ // open status filter
+ dataJobExecutionsPage.openStatusFilter();
+
+ // verify exist
+ 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",
+ ]);
+
+ // close status filter
+ dataJobExecutionsPage.closeFilter();
+
+ // verify doesn't exist
+ dataJobExecutionsPage.getDataGridPopupFilter().should("not.exist");
+
+ // verify current URL has appended default sort by startTime descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ },
+ });
- dataJobExecutionsPage.getDataGrid().should('exist');
+ // open status filter and select all available values and close the filter
+ dataJobExecutionsPage.openStatusFilter();
+ dataJobExecutionsPage.filterByStatus("user_error");
+ dataJobExecutionsPage.filterByStatus("platform_error");
+ dataJobExecutionsPage.filterByStatus("succeeded");
+ dataJobExecutionsPage.filterByStatus("running");
+ dataJobExecutionsPage.filterByStatus("skipped");
+ dataJobExecutionsPage.filterByStatus("submitted");
+ dataJobExecutionsPage.filterByStatus("cancelled");
+ dataJobExecutionsPage.closeFilter();
+
+ // verify current URL has appended all execution statuses and sort by status ascending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ filter:
+ '{"status":"user_error,platform_error,succeeded,running,skipped,submitted,cancelled"}',
+ },
+ });
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
+ // open status filter and unselect statuses: platform_error, skipped, submitted, cancelled and close the filter
+ dataJobExecutionsPage.openStatusFilter();
+ dataJobExecutionsPage.clearFilterByStatus("platform_error");
+ dataJobExecutionsPage.clearFilterByStatus("skipped");
+ dataJobExecutionsPage.clearFilterByStatus("submitted");
+ dataJobExecutionsPage.clearFilterByStatus("cancelled");
+ dataJobExecutionsPage.closeFilter();
+
+ // verify current URL has appended execution statuses user_error, succeeded, running and sort by status ascending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ filter: '{"status":"user_error,succeeded,running"}',
+ },
+ });
+
+ // open status filter and unselect left statuses and close the filter
+ dataJobExecutionsPage.openStatusFilter();
+ dataJobExecutionsPage.clearFilterByStatus("user_error");
+ dataJobExecutionsPage.clearFilterByStatus("succeeded");
+ dataJobExecutionsPage.clearFilterByStatus("running");
+ dataJobExecutionsPage.closeFilter();
+
+ // verify current URL has appended only sort by status descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ },
+ });
});
- it('should verify start then cancel execution works', () => {
- const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(shortLivedTestJobWithDeployFixture.team, shortLivedTestJobWithDeployFixture.job_name);
+ it("should verify type filter options are rendered and behaves correctly", () => {
+ const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(
+ longLivedFailingJobFixture.team,
+ longLivedFailingJobFixture.job_name,
+ );
+
+ // open type filter
+ dataJobExecutionsPage.openTypeFilter();
+
+ // verify exist
+ dataJobExecutionsPage.getDataGridPopupFilter().should("exist");
+ dataJobExecutionsPage
+ .getDataGridExecTypeFilterLabel("manual")
+ .should("exist")
+ .should("have.text", "Manual");
+ dataJobExecutionsPage
+ .getDataGridExecTypeFilterLabel("scheduled")
+ .should("exist")
+ .should("have.text", "Scheduled");
+
+ // close type filter
+ dataJobExecutionsPage.closeFilter();
+
+ // verify doesn't exist
+ dataJobExecutionsPage.getDataGridPopupFilter().should("not.exist");
+
+ // verify current URL has appended default sort by startTime descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ },
+ });
- DataJobManageExecutionsPage.waitForDataJobToNotHaveRunningExecution();
+ // open type filter and select manual execution trigger and close
+ dataJobExecutionsPage.openTypeFilter();
+ dataJobExecutionsPage.filterByType("manual");
+ dataJobExecutionsPage.closeFilter();
+
+ // verify cell elements
+ dataJobExecutionsPage
+ .getDataGridExecTypeContainers("scheduled")
+ .should("have.length", 0);
+
+ // verify current URL has appended manual execution trigger and sort by type ascending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ filter: '{"type":"manual"}',
+ },
+ });
+
+ // open type filter and select scheduled execution trigger and close
+ dataJobExecutionsPage.openTypeFilter();
+ dataJobExecutionsPage.filterByType("scheduled");
+ dataJobExecutionsPage.closeFilter();
+
+ // verify cell elements
+ dataJobExecutionsPage
+ .getDataGridExecTypeContainers("manual")
+ .should("have.length.gte", 0);
+ dataJobExecutionsPage
+ .getDataGridExecTypeContainers("scheduled")
+ .should("have.length.gte", 0);
+
+ // verify current URL has appended manual and scheduled execution trigger and sort by type ascending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ filter: '{"type":"manual,scheduled"}',
+ },
+ });
+
+ // open type filter and unselect scheduled and manual execution triggers and close filter
+ dataJobExecutionsPage.openTypeFilter();
+ dataJobExecutionsPage.clearFilterByType("scheduled");
+ dataJobExecutionsPage.clearFilterByType("manual");
+ dataJobExecutionsPage.closeFilter();
+
+ // verify cell elements
+ dataJobExecutionsPage
+ .getDataGridExecTypeContainers("manual")
+ .should("have.length.gte", 0);
+ dataJobExecutionsPage
+ .getDataGridExecTypeContainers("scheduled")
+ .should("have.length.gte", 0);
+
+ // verify current URL has appended only sort by type descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ },
+ });
+ });
- dataJobExecutionsPage.getExecutionsTab().should('exist').should('have.class', 'active');
+ it("should verify duration filter render input and filters correctly", () => {
+ const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(
+ longLivedFailingJobFixture.team,
+ longLivedFailingJobFixture.job_name,
+ );
+
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ // verify current URL has appended default sort by startTime descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ },
+ });
- // Execute data job and check if the execution status after that is Running or Submitted
- dataJobExecutionsPage.executeNow(true);
- dataJobExecutionsPage
- .getExecutionStatus()
- .first()
- .contains(/Running|Submitted/);
+ // open duration filter
+ dataJobExecutionsPage.openDurationFilter();
+
+ // verify exist fill with data na verify again
+ dataJobExecutionsPage.getDataGridPopupFilter().should("exist");
+ dataJobExecutionsPage.typeToTextFilterInput("100s");
+ dataJobExecutionsPage.getDataGridRows().should("have.length", 0);
+
+ // verify current URL has appended default sort by startTime descending and new value for id xyxyxy
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ filter: '{"duration":"100s"}',
+ },
+ });
- // Cancel data job execution and check if the status after that is Cancelled
- dataJobExecutionsPage.cancelExecution(true);
- dataJobExecutionsPage.getExecutionStatus().first().should('contains.text', 'Canceled');
+ // clear filter and verify
+ dataJobExecutionsPage.clearTextFilterInput();
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ // close id filter
+ dataJobExecutionsPage.closeFilter();
+
+ // verify doesn't exist
+ dataJobExecutionsPage.getDataGridPopupFilter().should("not.exist");
+
+ // verify current URL has appended default sort by startTime descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ },
+ });
});
- });
- describe('extended', () => {
- it('should verify on URL navigate to Executions will open the page', () => {
- const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(longLivedFailingJobFixture.team, longLivedFailingJobFixture.job_name);
+ it("should verify execution start time filter render input and filters correctly", () => {
+ const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(
+ longLivedFailingJobFixture.team,
+ longLivedFailingJobFixture.job_name,
+ );
+
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ // verify current URL has appended default sort by startTime descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ },
+ });
+
+ // open exec start time filter
+ dataJobExecutionsPage.openExecStartFilter();
+
+ // verify exist fill with data na verify again
+ dataJobExecutionsPage.getDataGridPopupFilter().should("exist");
+ dataJobExecutionsPage
+ .generateExecStartFilterValue()
+ .then((filterValue) => {
+ // type generated filter value
+ dataJobExecutionsPage.typeToTextFilterInput(filterValue);
+
+ // verify only cells that match the value are rendered
+ dataJobExecutionsPage
+ .getDataGridExecStartCells()
+ .then(($cells) => {
+ const foundCells = Array.from($cells).map((cell) =>
+ new RegExp(`${filterValue}$`).test(
+ `${cell.innerText?.trim()}`,
+ ),
+ );
+
+ return foundCells.length;
+ })
+ .should("gt", 0);
- dataJobExecutionsPage
+ // verify current URL has appended default sort by startTime descending and new value for startTime ${filterValue}
+ dataJobExecutionsPage
.getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
})
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}'
- }
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ filter: `{"startTime":"${filterValue}"}`,
+ },
});
+ });
- dataJobExecutionsPage.getDetailsTab().should('exist').should('not.have.class', 'active');
+ // clear filter and verify
+ dataJobExecutionsPage.clearTextFilterInput();
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ // close start time filter
+ dataJobExecutionsPage.closeFilter();
+
+ // verify doesn't exist
+ dataJobExecutionsPage.getDataGridPopupFilter().should("not.exist");
+
+ // verify current URL has appended default sort by startTime descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ },
+ });
+ });
- dataJobExecutionsPage.getExecutionsTab().should('exist').should('have.class', 'active');
+ it("should verify execution end time filter render input and filters correctly", () => {
+ const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(
+ longLivedFailingJobFixture.team,
+ longLivedFailingJobFixture.job_name,
+ );
+
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ // verify current URL has appended default sort by startTime descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ },
+ });
- dataJobExecutionsPage.getDataGrid().should('exist');
- });
+ // open exec end time filter
+ dataJobExecutionsPage.openExecEndFilter();
+
+ // verify exist fill with data na verify again
+ dataJobExecutionsPage.getDataGridPopupFilter().should("exist");
+ dataJobExecutionsPage
+ .generateExecEndFilterValue()
+ .then((filterValue) => {
+ // type generated filter value
+ dataJobExecutionsPage.typeToTextFilterInput(filterValue);
+
+ // verify only cells that match the value are rendered
+ dataJobExecutionsPage
+ .getDataGridExecEndCells()
+ .then(($cells) => {
+ const foundCells = Array.from($cells).map((cell) =>
+ new RegExp(`${filterValue}$`).test(
+ `${cell.innerText?.trim()}`,
+ ),
+ );
+
+ return foundCells.length;
+ })
+ .should("gt", 0);
- it('should verify time period is in correct format', () => {
- const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(longLivedFailingJobFixture.team, longLivedFailingJobFixture.job_name);
+ // verify current URL has appended default sort by startTime descending and new value for endTime ${filterValue}
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ filter: `{"endTime":"${filterValue}"}`,
+ },
+ });
+ });
- 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)$`));
+ // clear filter and verify
+ dataJobExecutionsPage.clearTextFilterInput();
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ // close start time filter
+ dataJobExecutionsPage.closeFilter();
+
+ // verify doesn't exist
+ dataJobExecutionsPage.getDataGridPopupFilter().should("not.exist");
+
+ // verify current URL has appended default sort by startTime descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ },
+ });
});
- it('should verify refresh button will show spinner and then load data', () => {
- const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(longLivedFailingJobFixture.team, longLivedFailingJobFixture.job_name);
+ it("should verify execution id filter render input and filters correctly", () => {
+ const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(
+ longLivedFailingJobFixture.team,
+ longLivedFailingJobFixture.job_name,
+ );
+
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ // verify current URL has appended default sort by startTime descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ },
+ });
- // verify before
- dataJobExecutionsPage.getDataGrid().should('exist');
- dataJobExecutionsPage.getExecLoadingSpinner().should('not.exist');
- dataJobExecutionsPage.getDataGridSpinner().should('not.exist');
+ // open exec ID filter
+ dataJobExecutionsPage.openIDFilter();
+
+ // verify exist fill with data na verify again
+ dataJobExecutionsPage.getDataGridPopupFilter().should("exist");
+ // type job name as filter value
+ dataJobExecutionsPage.typeToTextFilterInput(
+ longLivedFailingJobFixture.job_name,
+ );
+
+ // verify only cells that match the value are rendered
+ dataJobExecutionsPage
+ .getDataGridExecIDCells()
+ .then(($cells) => {
+ const foundCells = Array.from($cells).map((cell) =>
+ new RegExp(`^${longLivedFailingJobFixture.job_name}-\d+$`).test(
+ `${cell.innerText?.trim()}`,
+ ),
+ );
+
+ return foundCells.length;
+ })
+ .should("gt", 0);
+
+ // verify current URL has appended default sort by startTime descending and new value for endTime ${filterValue}
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ filter: `{"id":"${longLivedFailingJobFixture.job_name}"}`,
+ },
+ });
- // trigger refresh
- dataJobExecutionsPage.waitForActionThinkingTime();
- dataJobExecutionsPage.refreshExecData();
+ // clear filter and type random text then verify
+ dataJobExecutionsPage.clearTextFilterInput();
+ dataJobExecutionsPage.typeToTextFilterInput("xyxyxy");
+ dataJobExecutionsPage.getDataGridRows().should("have.length", 0);
+
+ // verify current URL has appended default sort by startTime descending and new value for id xyxyxy
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ filter: '{"id":"xyxyxy"}',
+ },
+ });
+
+ // clear filter and verify
+ dataJobExecutionsPage.clearTextFilterInput();
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ // close start time filter
+ dataJobExecutionsPage.closeFilter();
+
+ // verify doesn't exist
+ dataJobExecutionsPage.getDataGridPopupFilter().should("not.exist");
+
+ // verify current URL has appended default sort by startTime descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ },
+ });
+ });
- // verify while refreshing
- dataJobExecutionsPage.getDataGrid().should('exist');
- dataJobExecutionsPage.getExecLoadingSpinner().should('exist');
- dataJobExecutionsPage.getDataGridSpinner().should('exist');
+ it("should verify version filter render input and filters correctly", () => {
+ const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(
+ longLivedFailingJobFixture.team,
+ longLivedFailingJobFixture.job_name,
+ );
+
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ // verify current URL has appended default sort by startTime descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ },
+ });
- // wait loading data to finish
- dataJobExecutionsPage.waitForGridDataLoad();
+ // open version filter
+ dataJobExecutionsPage.openVersionFilter();
+
+ // verify exist fill with data na verify again
+ dataJobExecutionsPage.getDataGridPopupFilter().should("exist");
+ dataJobExecutionsPage.typeToTextFilterInput("xyxyxy");
+ dataJobExecutionsPage.getDataGridRows().should("have.length", 0);
+
+ // verify current URL has appended default sort by startTime descending and new value for jobVersion xyxyxy
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ filter: '{"jobVersion":"xyxyxy"}',
+ },
+ });
- // verify after refresh
- dataJobExecutionsPage.getDataGrid().should('exist');
- dataJobExecutionsPage.getExecLoadingSpinner().should('not.exist');
- dataJobExecutionsPage.getDataGridSpinner().should('not.exist');
+ // clear filter and verify
+ dataJobExecutionsPage.clearTextFilterInput();
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ // close version filter
+ dataJobExecutionsPage.closeFilter();
+
+ // verify doesn't exist
+ dataJobExecutionsPage.getDataGridPopupFilter().should("not.exist");
+
+ // verify current URL has appended default sort by startTime descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ },
+ });
});
+ });
+
+ describe("DataGrid Sort", () => {
+ it("should verify status sort behaves correctly", () => {
+ const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(
+ longLivedFailingJobFixture.team,
+ longLivedFailingJobFixture.job_name,
+ );
+
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ dataJobExecutionsPage
+ .getDataGridExecStatusHeader()
+ .should("exist")
+ .invoke("attr", "aria-sort")
+ .should("eq", "none");
+
+ // verify current URL has appended default sort by startTime descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ },
+ });
- describe('DataGrid Filters', () => {
- it('should verify status filter options are rendered and behaves correctly', () => {
- const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(longLivedFailingJobFixture.team, longLivedFailingJobFixture.job_name);
-
- // open status filter
- dataJobExecutionsPage.openStatusFilter();
-
- // verify exist
- 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']);
-
- // close status filter
- dataJobExecutionsPage.closeFilter();
-
- // verify doesn't exist
- dataJobExecutionsPage.getDataGridPopupFilter().should('not.exist');
-
- // verify current URL has appended default sort by startTime descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}'
- }
- });
-
- // open status filter and select all available values and close the filter
- dataJobExecutionsPage.openStatusFilter();
- dataJobExecutionsPage.filterByStatus('user_error');
- dataJobExecutionsPage.filterByStatus('platform_error');
- dataJobExecutionsPage.filterByStatus('succeeded');
- dataJobExecutionsPage.filterByStatus('running');
- dataJobExecutionsPage.filterByStatus('skipped');
- dataJobExecutionsPage.filterByStatus('submitted');
- dataJobExecutionsPage.filterByStatus('cancelled');
- dataJobExecutionsPage.closeFilter();
-
- // verify current URL has appended all execution statuses and sort by status ascending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}',
- filter: '{"status":"user_error,platform_error,succeeded,running,skipped,submitted,cancelled"}'
- }
- });
-
- // open status filter and unselect statuses: platform_error, skipped, submitted, cancelled and close the filter
- dataJobExecutionsPage.openStatusFilter();
- dataJobExecutionsPage.clearFilterByStatus('platform_error');
- dataJobExecutionsPage.clearFilterByStatus('skipped');
- dataJobExecutionsPage.clearFilterByStatus('submitted');
- dataJobExecutionsPage.clearFilterByStatus('cancelled');
- dataJobExecutionsPage.closeFilter();
-
- // verify current URL has appended execution statuses user_error, succeeded, running and sort by status ascending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}',
- filter: '{"status":"user_error,succeeded,running"}'
- }
- });
-
- // open status filter and unselect left statuses and close the filter
- dataJobExecutionsPage.openStatusFilter();
- dataJobExecutionsPage.clearFilterByStatus('user_error');
- dataJobExecutionsPage.clearFilterByStatus('succeeded');
- dataJobExecutionsPage.clearFilterByStatus('running');
- dataJobExecutionsPage.closeFilter();
-
- // verify current URL has appended only sort by status descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}'
- }
- });
+ // sort by status ascending
+ dataJobExecutionsPage.sortByExecStatus();
+
+ // verify sort by status is ascending
+ dataJobExecutionsPage
+ .getDataGridExecStatusHeader()
+ .should("exist")
+ .invoke("attr", "aria-sort")
+ .should("eq", "ascending");
+
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ // verify current URL has appended sort by status ascending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"status":1}',
+ },
});
- it('should verify type filter options are rendered and behaves correctly', () => {
- const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(longLivedFailingJobFixture.team, longLivedFailingJobFixture.job_name);
-
- // open type filter
- dataJobExecutionsPage.openTypeFilter();
-
- // verify exist
- dataJobExecutionsPage.getDataGridPopupFilter().should('exist');
- dataJobExecutionsPage.getDataGridExecTypeFilterLabel('manual').should('exist').should('have.text', 'Manual');
- dataJobExecutionsPage.getDataGridExecTypeFilterLabel('scheduled').should('exist').should('have.text', 'Scheduled');
-
- // close type filter
- dataJobExecutionsPage.closeFilter();
-
- // verify doesn't exist
- dataJobExecutionsPage.getDataGridPopupFilter().should('not.exist');
-
- // verify current URL has appended default sort by startTime descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}'
- }
- });
-
- // open type filter and select manual execution trigger and close
- dataJobExecutionsPage.openTypeFilter();
- dataJobExecutionsPage.filterByType('manual');
- dataJobExecutionsPage.closeFilter();
-
- // verify cell elements
- dataJobExecutionsPage.getDataGridExecTypeContainers('scheduled').should('have.length', 0);
-
- // verify current URL has appended manual execution trigger and sort by type ascending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}',
- filter: '{"type":"manual"}'
- }
- });
-
- // open type filter and select scheduled execution trigger and close
- dataJobExecutionsPage.openTypeFilter();
- dataJobExecutionsPage.filterByType('scheduled');
- dataJobExecutionsPage.closeFilter();
-
- // verify cell elements
- dataJobExecutionsPage.getDataGridExecTypeContainers('manual').should('have.length.gte', 0);
- dataJobExecutionsPage.getDataGridExecTypeContainers('scheduled').should('have.length.gte', 0);
-
- // verify current URL has appended manual and scheduled execution trigger and sort by type ascending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}',
- filter: '{"type":"manual,scheduled"}'
- }
- });
-
- // open type filter and unselect scheduled and manual execution triggers and close filter
- dataJobExecutionsPage.openTypeFilter();
- dataJobExecutionsPage.clearFilterByType('scheduled');
- dataJobExecutionsPage.clearFilterByType('manual');
- dataJobExecutionsPage.closeFilter();
-
- // verify cell elements
- dataJobExecutionsPage.getDataGridExecTypeContainers('manual').should('have.length.gte', 0);
- dataJobExecutionsPage.getDataGridExecTypeContainers('scheduled').should('have.length.gte', 0);
-
- // verify current URL has appended only sort by type descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}'
- }
- });
+ // sort by status descending
+ dataJobExecutionsPage.sortByExecStatus();
+
+ // verify sort by status is descending
+ dataJobExecutionsPage
+ .getDataGridExecStatusHeader()
+ .should("exist")
+ .invoke("attr", "aria-sort")
+ .should("eq", "descending");
+
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ // verify current URL has appended sort by status descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"status":-1}',
+ },
});
+ });
- it('should verify duration filter render input and filters correctly', () => {
- const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(longLivedFailingJobFixture.team, longLivedFailingJobFixture.job_name);
-
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- // verify current URL has appended default sort by startTime descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}'
- }
- });
-
- // open duration filter
- dataJobExecutionsPage.openDurationFilter();
-
- // verify exist fill with data na verify again
- dataJobExecutionsPage.getDataGridPopupFilter().should('exist');
- dataJobExecutionsPage.typeToTextFilterInput('100s');
- dataJobExecutionsPage.getDataGridRows().should('have.length', 0);
-
- // verify current URL has appended default sort by startTime descending and new value for id xyxyxy
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}',
- filter: '{"duration":"100s"}'
- }
- });
-
- // clear filter and verify
- dataJobExecutionsPage.clearTextFilterInput();
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- // close id filter
- dataJobExecutionsPage.closeFilter();
-
- // verify doesn't exist
- dataJobExecutionsPage.getDataGridPopupFilter().should('not.exist');
-
- // verify current URL has appended default sort by startTime descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}'
- }
- });
+ it("should verify type sort behaves correctly", () => {
+ const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(
+ longLivedFailingJobFixture.team,
+ longLivedFailingJobFixture.job_name,
+ );
+
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ dataJobExecutionsPage
+ .getDataGridExecTypeHeader()
+ .should("exist")
+ .invoke("attr", "aria-sort")
+ .should("eq", "none");
+
+ // verify current URL has appended default sort by startTime descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ },
});
- it('should verify execution start time filter render input and filters correctly', () => {
- const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(longLivedFailingJobFixture.team, longLivedFailingJobFixture.job_name);
-
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- // verify current URL has appended default sort by startTime descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}'
- }
- });
-
- // open exec start time filter
- dataJobExecutionsPage.openExecStartFilter();
-
- // verify exist fill with data na verify again
- dataJobExecutionsPage.getDataGridPopupFilter().should('exist');
- dataJobExecutionsPage.generateExecStartFilterValue().then((filterValue) => {
- // type generated filter value
- dataJobExecutionsPage.typeToTextFilterInput(filterValue);
-
- // verify only cells that match the value are rendered
- dataJobExecutionsPage
- .getDataGridExecStartCells()
- .then(($cells) => {
- const foundCells = Array.from($cells).map((cell) => new RegExp(`${filterValue}$`).test(`${cell.innerText?.trim()}`));
-
- return foundCells.length;
- })
- .should('gt', 0);
-
- // verify current URL has appended default sort by startTime descending and new value for startTime ${filterValue}
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}',
- filter: `{"startTime":"${filterValue}"}`
- }
- });
- });
+ // sort by type ascending
+ dataJobExecutionsPage.sortByExecType();
+
+ // verify sort is ascending
+ dataJobExecutionsPage
+ .getDataGridExecTypeHeader()
+ .should("exist")
+ .invoke("attr", "aria-sort")
+ .should("eq", "ascending");
+
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ // verify current URL has appended sort by type ascending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"type":1}',
+ },
+ });
- // clear filter and verify
- dataJobExecutionsPage.clearTextFilterInput();
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- // close start time filter
- dataJobExecutionsPage.closeFilter();
-
- // verify doesn't exist
- dataJobExecutionsPage.getDataGridPopupFilter().should('not.exist');
-
- // verify current URL has appended default sort by startTime descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}'
- }
- });
+ // sort by type descending
+ dataJobExecutionsPage.sortByExecType();
+
+ // verify sort is descending
+ dataJobExecutionsPage
+ .getDataGridExecTypeHeader()
+ .should("exist")
+ .invoke("attr", "aria-sort")
+ .should("eq", "descending");
+
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ // verify current URL has appended sort by type descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"type":-1}',
+ },
});
+ });
- it('should verify execution end time filter render input and filters correctly', () => {
- const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(longLivedFailingJobFixture.team, longLivedFailingJobFixture.job_name);
-
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- // verify current URL has appended default sort by startTime descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}'
- }
- });
-
- // open exec end time filter
- dataJobExecutionsPage.openExecEndFilter();
-
- // verify exist fill with data na verify again
- dataJobExecutionsPage.getDataGridPopupFilter().should('exist');
- dataJobExecutionsPage.generateExecEndFilterValue().then((filterValue) => {
- // type generated filter value
- dataJobExecutionsPage.typeToTextFilterInput(filterValue);
-
- // verify only cells that match the value are rendered
- dataJobExecutionsPage
- .getDataGridExecEndCells()
- .then(($cells) => {
- const foundCells = Array.from($cells).map((cell) => new RegExp(`${filterValue}$`).test(`${cell.innerText?.trim()}`));
-
- return foundCells.length;
- })
- .should('gt', 0);
-
- // verify current URL has appended default sort by startTime descending and new value for endTime ${filterValue}
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}',
- filter: `{"endTime":"${filterValue}"}`
- }
- });
+ it("should verify duration sort works", () => {
+ const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(
+ longLivedFailingJobFixture.team,
+ longLivedFailingJobFixture.job_name,
+ );
+
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ dataJobExecutionsPage
+ .getDataGridExecDurationHeader()
+ .should("exist")
+ .invoke("attr", "aria-sort")
+ .should("eq", "none");
+
+ // verify current URL has appended default sort by startTime descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ },
+ });
+
+ // sort by duration ascending
+ 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);
+
+ // verify current URL has appended sort by duration ascending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"duration":1}',
+ },
+ });
- // clear filter and verify
- dataJobExecutionsPage.clearTextFilterInput();
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- // close start time filter
- dataJobExecutionsPage.closeFilter();
-
- // verify doesn't exist
- dataJobExecutionsPage.getDataGridPopupFilter().should('not.exist');
-
- // verify current URL has appended default sort by startTime descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}'
- }
- });
+ // sort by duration descending
+ 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);
+
+ // verify current URL has appended sort by duration descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"duration":-1}',
+ },
});
+ });
- it('should verify execution id filter render input and filters correctly', () => {
- const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(longLivedFailingJobFixture.team, longLivedFailingJobFixture.job_name);
-
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- // verify current URL has appended default sort by startTime descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}'
- }
- });
-
- // open exec ID filter
- dataJobExecutionsPage.openIDFilter();
-
- // verify exist fill with data na verify again
- dataJobExecutionsPage.getDataGridPopupFilter().should('exist');
- // type job name as filter value
- dataJobExecutionsPage.typeToTextFilterInput(longLivedFailingJobFixture.job_name);
-
- // verify only cells that match the value are rendered
- dataJobExecutionsPage
- .getDataGridExecIDCells()
- .then(($cells) => {
- const foundCells = Array.from($cells).map((cell) => new RegExp(`^${longLivedFailingJobFixture.job_name}-\d+$`).test(`${cell.innerText?.trim()}`));
-
- return foundCells.length;
- })
- .should('gt', 0);
-
- // verify current URL has appended default sort by startTime descending and new value for endTime ${filterValue}
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}',
- filter: `{"id":"${longLivedFailingJobFixture.job_name}"}`
- }
- });
-
- // clear filter and type random text then verify
- dataJobExecutionsPage.clearTextFilterInput();
- dataJobExecutionsPage.typeToTextFilterInput('xyxyxy');
- dataJobExecutionsPage.getDataGridRows().should('have.length', 0);
-
- // verify current URL has appended default sort by startTime descending and new value for id xyxyxy
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}',
- filter: '{"id":"xyxyxy"}'
- }
- });
-
- // clear filter and verify
- dataJobExecutionsPage.clearTextFilterInput();
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- // close start time filter
- dataJobExecutionsPage.closeFilter();
-
- // verify doesn't exist
- dataJobExecutionsPage.getDataGridPopupFilter().should('not.exist');
-
- // verify current URL has appended default sort by startTime descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}'
- }
- });
+ it("should verify execution start time sort works", () => {
+ const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(
+ longLivedFailingJobFixture.team,
+ longLivedFailingJobFixture.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);
+
+ // verify current URL has appended default sort by startTime descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ },
});
- it('should verify version filter render input and filters correctly', () => {
- const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(longLivedFailingJobFixture.team, longLivedFailingJobFixture.job_name);
-
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- // verify current URL has appended default sort by startTime descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}'
- }
- });
-
- // open version filter
- dataJobExecutionsPage.openVersionFilter();
-
- // verify exist fill with data na verify again
- dataJobExecutionsPage.getDataGridPopupFilter().should('exist');
- dataJobExecutionsPage.typeToTextFilterInput('xyxyxy');
- dataJobExecutionsPage.getDataGridRows().should('have.length', 0);
-
- // verify current URL has appended default sort by startTime descending and new value for jobVersion xyxyxy
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}',
- filter: '{"jobVersion":"xyxyxy"}'
- }
- });
-
- // clear filter and verify
- dataJobExecutionsPage.clearTextFilterInput();
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- // close version filter
- dataJobExecutionsPage.closeFilter();
-
- // verify doesn't exist
- dataJobExecutionsPage.getDataGridPopupFilter().should('not.exist');
-
- // verify current URL has appended default sort by startTime descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}'
- }
- });
+ // sort by exec start ascending
+ 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);
+
+ // verify current URL has appended sort by duration ascending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":1}',
+ },
});
});
- describe('DataGrid Sort', () => {
- it('should verify status sort behaves correctly', () => {
- const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(longLivedFailingJobFixture.team, longLivedFailingJobFixture.job_name);
-
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- dataJobExecutionsPage.getDataGridExecStatusHeader().should('exist').invoke('attr', 'aria-sort').should('eq', 'none');
-
- // verify current URL has appended default sort by startTime descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}'
- }
- });
-
- // sort by status ascending
- dataJobExecutionsPage.sortByExecStatus();
-
- // verify sort by status is ascending
- dataJobExecutionsPage.getDataGridExecStatusHeader().should('exist').invoke('attr', 'aria-sort').should('eq', 'ascending');
-
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- // verify current URL has appended sort by status ascending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"status":1}'
- }
- });
-
- // sort by status descending
- dataJobExecutionsPage.sortByExecStatus();
-
- // verify sort by status is descending
- dataJobExecutionsPage.getDataGridExecStatusHeader().should('exist').invoke('attr', 'aria-sort').should('eq', 'descending');
-
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- // verify current URL has appended sort by status descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"status":-1}'
- }
- });
+ it("should verify execution end time sort works", () => {
+ const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(
+ longLivedFailingJobFixture.team,
+ longLivedFailingJobFixture.job_name,
+ );
+
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ dataJobExecutionsPage
+ .getDataGridExecEndHeader()
+ .should("exist")
+ .invoke("attr", "aria-sort")
+ .should("eq", "none");
+
+ // verify current URL has appended default sort by startTime descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ },
});
- it('should verify type sort behaves correctly', () => {
- const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(longLivedFailingJobFixture.team, longLivedFailingJobFixture.job_name);
-
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- dataJobExecutionsPage.getDataGridExecTypeHeader().should('exist').invoke('attr', 'aria-sort').should('eq', 'none');
-
- // verify current URL has appended default sort by startTime descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}'
- }
- });
-
- // sort by type ascending
- dataJobExecutionsPage.sortByExecType();
-
- // verify sort is ascending
- dataJobExecutionsPage.getDataGridExecTypeHeader().should('exist').invoke('attr', 'aria-sort').should('eq', 'ascending');
-
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- // verify current URL has appended sort by type ascending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"type":1}'
- }
- });
-
- // sort by type descending
- dataJobExecutionsPage.sortByExecType();
-
- // verify sort is descending
- dataJobExecutionsPage.getDataGridExecTypeHeader().should('exist').invoke('attr', 'aria-sort').should('eq', 'descending');
-
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- // verify current URL has appended sort by type descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"type":-1}'
- }
- });
+ // sort by exec end ascending
+ 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);
+
+ // verify current URL has appended sort by endTime ascending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"endTime":1}',
+ },
});
- it('should verify duration sort works', () => {
- const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(longLivedFailingJobFixture.team, longLivedFailingJobFixture.job_name);
-
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- dataJobExecutionsPage.getDataGridExecDurationHeader().should('exist').invoke('attr', 'aria-sort').should('eq', 'none');
-
- // verify current URL has appended default sort by startTime descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}'
- }
- });
-
- // sort by duration ascending
- 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);
-
- // verify current URL has appended sort by duration ascending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"duration":1}'
- }
- });
-
- // sort by duration descending
- 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);
-
- // verify current URL has appended sort by duration descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"duration":-1}'
- }
- });
+ // sort by exec end time descending
+ 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);
+
+ // verify current URL has appended sort by endTime descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"endTime":-1}',
+ },
});
+ });
- it('should verify execution start time sort works', () => {
- const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(longLivedFailingJobFixture.team, longLivedFailingJobFixture.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);
-
- // verify current URL has appended default sort by startTime descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}'
- }
- });
-
- // sort by exec start ascending
- 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);
-
- // verify current URL has appended sort by duration ascending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":1}'
- }
- });
+ it("should verify execution ID sort works", () => {
+ const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(
+ longLivedFailingJobFixture.team,
+ longLivedFailingJobFixture.job_name,
+ );
+
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ dataJobExecutionsPage
+ .getDataGridExecIDHeader()
+ .should("exist")
+ .invoke("attr", "aria-sort")
+ .should("eq", "none");
+
+ // verify current URL has appended default sort by startTime descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ },
});
- it('should verify execution end time sort works', () => {
- const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(longLivedFailingJobFixture.team, longLivedFailingJobFixture.job_name);
-
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- dataJobExecutionsPage.getDataGridExecEndHeader().should('exist').invoke('attr', 'aria-sort').should('eq', 'none');
-
- // verify current URL has appended default sort by startTime descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}'
- }
- });
-
- // sort by exec end ascending
- 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);
-
- // verify current URL has appended sort by endTime ascending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"endTime":1}'
- }
- });
-
- // sort by exec end time descending
- 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);
-
- // verify current URL has appended sort by endTime descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"endTime":-1}'
- }
- });
+ // sort by ID ascending
+ dataJobExecutionsPage.sortByExecID();
+
+ dataJobExecutionsPage
+ .getDataGridExecIDHeader()
+ .should("exist")
+ .invoke("attr", "aria-sort")
+ .should("eq", "ascending");
+
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ dataJobExecutionsPage
+ .getDataGridExecIDCell(1)
+ .invoke("text")
+ .invoke("trim")
+ .then((elText1) => {
+ return dataJobExecutionsPage
+ .getDataGridExecIDCell(2)
+ .invoke("text")
+ .invoke("trim")
+ .then((elText2) => {
+ return elText2 > elText1;
+ });
+ })
+ .should("be.true");
+
+ // verify current URL has appended sort by id ascending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"id":1}',
+ },
});
- it('should verify execution ID sort works', () => {
- const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(longLivedFailingJobFixture.team, longLivedFailingJobFixture.job_name);
-
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- dataJobExecutionsPage.getDataGridExecIDHeader().should('exist').invoke('attr', 'aria-sort').should('eq', 'none');
-
- // verify current URL has appended default sort by startTime descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}'
- }
- });
-
- // sort by ID ascending
- dataJobExecutionsPage.sortByExecID();
-
- dataJobExecutionsPage.getDataGridExecIDHeader().should('exist').invoke('attr', 'aria-sort').should('eq', 'ascending');
-
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- dataJobExecutionsPage
- .getDataGridExecIDCell(1)
- .invoke('text')
- .invoke('trim')
- .then((elText1) => {
- return dataJobExecutionsPage
- .getDataGridExecIDCell(2)
- .invoke('text')
- .invoke('trim')
- .then((elText2) => {
- return elText2 > elText1;
- });
- })
- .should('be.true');
-
- // verify current URL has appended sort by id ascending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"id":1}'
- }
- });
-
- // sort by ID descending
- dataJobExecutionsPage.sortByExecID();
-
- dataJobExecutionsPage.getDataGridExecIDHeader().should('exist').invoke('attr', 'aria-sort').should('eq', 'descending');
-
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- dataJobExecutionsPage
- .getDataGridExecIDCell(1)
- .invoke('text')
- .invoke('trim')
- .then((elText1) => {
- return dataJobExecutionsPage
- .getDataGridExecIDCell(2)
- .invoke('text')
- .invoke('trim')
- .then((elText2) => {
- return elText1 > elText2;
- });
- })
- .should('be.true');
-
- // verify current URL has appended sort by id descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"id":-1}'
- }
- });
+ // sort by ID descending
+ dataJobExecutionsPage.sortByExecID();
+
+ dataJobExecutionsPage
+ .getDataGridExecIDHeader()
+ .should("exist")
+ .invoke("attr", "aria-sort")
+ .should("eq", "descending");
+
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ dataJobExecutionsPage
+ .getDataGridExecIDCell(1)
+ .invoke("text")
+ .invoke("trim")
+ .then((elText1) => {
+ return dataJobExecutionsPage
+ .getDataGridExecIDCell(2)
+ .invoke("text")
+ .invoke("trim")
+ .then((elText2) => {
+ return elText1 > elText2;
+ });
+ })
+ .should("be.true");
+
+ // verify current URL has appended sort by id descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"id":-1}',
+ },
});
+ });
- it('should verify execution version sort works', () => {
- const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(longLivedFailingJobFixture.team, longLivedFailingJobFixture.job_name);
-
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- dataJobExecutionsPage.getDataGridExecVersionHeader().should('exist').invoke('attr', 'aria-sort').should('eq', 'none');
-
- // verify current URL has appended default sort by startTime descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}'
- }
- });
-
- // sort by version ascending
- dataJobExecutionsPage.sortByExecVersion();
-
- dataJobExecutionsPage.getDataGridExecVersionHeader().should('exist').invoke('attr', 'aria-sort').should('eq', 'ascending');
-
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- dataJobExecutionsPage
- .getDataGridExecVersionCell(1)
- .invoke('text')
- .invoke('trim')
- .then((elText1) => {
- return dataJobExecutionsPage
- .getDataGridExecVersionCell(2)
- .invoke('text')
- .invoke('trim')
- .then((elText2) => {
- return elText2 >= elText1;
- });
- })
- .should('be.true');
-
- // verify current URL has appended sort by job version ascending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"jobVersion":1}'
- }
- });
-
- // sort by version descending
- dataJobExecutionsPage.sortByExecVersion();
-
- dataJobExecutionsPage.getDataGridExecVersionHeader().should('exist').invoke('attr', 'aria-sort').should('eq', 'descending');
-
- dataJobExecutionsPage.getDataGridRows().should('have.length.gt', 0);
-
- dataJobExecutionsPage
- .getDataGridExecVersionCell(1)
- .invoke('text')
- .invoke('trim')
- .then((elText1) => {
- return dataJobExecutionsPage
- .getDataGridExecVersionCell(2)
- .invoke('text')
- .invoke('trim')
- .then((elText2) => {
- return elText1 >= elText2;
- });
- })
- .should('be.true');
-
- // verify current URL has appended sort by job version descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"jobVersion":-1}'
- }
- });
+ it("should verify execution version sort works", () => {
+ const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(
+ longLivedFailingJobFixture.team,
+ longLivedFailingJobFixture.job_name,
+ );
+
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ dataJobExecutionsPage
+ .getDataGridExecVersionHeader()
+ .should("exist")
+ .invoke("attr", "aria-sort")
+ .should("eq", "none");
+
+ // verify current URL has appended default sort by startTime descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ },
+ });
+
+ // sort by version ascending
+ dataJobExecutionsPage.sortByExecVersion();
+
+ dataJobExecutionsPage
+ .getDataGridExecVersionHeader()
+ .should("exist")
+ .invoke("attr", "aria-sort")
+ .should("eq", "ascending");
+
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ dataJobExecutionsPage
+ .getDataGridExecVersionCell(1)
+ .invoke("text")
+ .invoke("trim")
+ .then((elText1) => {
+ return dataJobExecutionsPage
+ .getDataGridExecVersionCell(2)
+ .invoke("text")
+ .invoke("trim")
+ .then((elText2) => {
+ return elText2 >= elText1;
+ });
+ })
+ .should("be.true");
+
+ // verify current URL has appended sort by job version ascending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"jobVersion":1}',
+ },
+ });
+
+ // sort by version descending
+ dataJobExecutionsPage.sortByExecVersion();
+
+ dataJobExecutionsPage
+ .getDataGridExecVersionHeader()
+ .should("exist")
+ .invoke("attr", "aria-sort")
+ .should("eq", "descending");
+
+ dataJobExecutionsPage.getDataGridRows().should("have.length.gt", 0);
+
+ dataJobExecutionsPage
+ .getDataGridExecVersionCell(1)
+ .invoke("text")
+ .invoke("trim")
+ .then((elText1) => {
+ return dataJobExecutionsPage
+ .getDataGridExecVersionCell(2)
+ .invoke("text")
+ .invoke("trim")
+ .then((elText2) => {
+ return elText1 >= elText2;
+ });
+ })
+ .should("be.true");
+
+ // verify current URL has appended sort by job version descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"jobVersion":-1}',
+ },
});
});
+ });
+
+ // !!! important tests order is very important, because generated url from 1st test is used in the second test
+ // the second test cannot be run without previously running the first test
+ describe("DataGrid Filters and Sort to URL", () => {
+ // value is assigned at the end of the 1st test and used in the 2nd test
+ let navigationUrlWithFiltersAndSort = "";
+
+ it("should verify multiple filters and sort are appended to URL", () => {
+ const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(
+ longLivedFailingJobFixture.team,
+ longLivedFailingJobFixture.job_name,
+ );
+
+ // verify current URL has appended default sort by startTime descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ },
+ });
- // !!! important tests order is very important, because generated url from 1st test is used in the second test
- // the second test cannot be run without previously running the first test
- describe('DataGrid Filters and Sort to URL', () => {
- // value is assigned at the end of the 1st test and used in the 2nd test
- let navigationUrlWithFiltersAndSort = '';
-
- it('should verify multiple filters and sort are appended to URL', () => {
- const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateTo(longLivedFailingJobFixture.team, longLivedFailingJobFixture.job_name);
-
- // verify current URL has appended default sort by startTime descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}'
- }
- });
-
- // open status filter and select user_error and close the filter
- dataJobExecutionsPage.openStatusFilter();
- dataJobExecutionsPage.filterByStatus('user_error');
- dataJobExecutionsPage.filterByStatus('platform_error');
- dataJobExecutionsPage.closeFilter();
-
- // verify current URL has appended filters execution status: user_error and platform_error, and sort by startTime descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}',
- filter: '{"status":"user_error,platform_error"}'
- }
- });
-
- // open type filter and select manual execution then verify, then select scheduled trigger and close
- dataJobExecutionsPage.openTypeFilter();
- dataJobExecutionsPage.filterByType('manual');
- dataJobExecutionsPage.getDataGridExecTypeContainers('scheduled').should('have.length', 0);
- dataJobExecutionsPage.filterByType('scheduled');
- dataJobExecutionsPage.closeFilter();
-
- // verify current URL has appended filters execution status: user_error and platform_error, trigger type: manual and scheduled, and sort by startTime descending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"startTime":-1}',
- filter: '{"status":"user_error,platform_error","type":"manual,scheduled"}'
- }
- });
-
- // sort by exec ID ascending
- dataJobExecutionsPage.sortByExecID();
-
- // open exec ID filter
- dataJobExecutionsPage.openIDFilter();
- // type job name as filter value
- dataJobExecutionsPage.typeToTextFilterInput(longLivedFailingJobFixture.job_name);
- // verify only cells that match the value are rendered
- dataJobExecutionsPage
- .getDataGridExecIDCells()
- .then(($cells) => {
- const foundCells = Array.from($cells).map((cell) => new RegExp(`^${longLivedFailingJobFixture.job_name}-\d+$`).test(`${cell.innerText?.trim()}`));
-
- return foundCells.length;
- })
- .should('gt', 0);
- // verify current URL has appended filters execution status: user_error and platform_error, trigger type: manual and scheduled, id: long_lived_job_name and sort by id ascending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"id":1}',
- filter: `{"status":"user_error,platform_error","type":"manual,scheduled","id":"${longLivedFailingJobFixture.job_name}"}`
- }
- });
-
- // open exec start time filter and type generated filterValue and close
- dataJobExecutionsPage.openExecStartFilter();
- dataJobExecutionsPage.generateExecStartFilterValue().then((filterValue) => {
- // type generated filter value
- dataJobExecutionsPage.typeToTextFilterInput(filterValue);
-
- // verify only cells that match the value are rendered
- dataJobExecutionsPage
- .getDataGridExecStartCells()
- .then(($cells) => {
- const foundCells = Array.from($cells).map((cell) => new RegExp(`${filterValue}$`).test(`${cell.innerText?.trim()}`));
-
- return foundCells.length;
- })
- .should('gt', 0);
-
- // verify current URL has appended filters execution status: user_error and platform_error, trigger type: manual and scheduled, id: long_lived_job_name, startTime: ${filterValue} and sort by id ascending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"id":1}',
- filter: `{"status":"user_error,platform_error","type":"manual,scheduled","id":"${longLivedFailingJobFixture.job_name}","startTime":"${filterValue}"}`
- }
- });
+ // open status filter and select user_error and close the filter
+ dataJobExecutionsPage.openStatusFilter();
+ dataJobExecutionsPage.filterByStatus("user_error");
+ dataJobExecutionsPage.filterByStatus("platform_error");
+ dataJobExecutionsPage.closeFilter();
+
+ // verify current URL has appended filters execution status: user_error and platform_error, and sort by startTime descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ filter: '{"status":"user_error,platform_error"}',
+ },
+ });
+
+ // open type filter and select manual execution then verify, then select scheduled trigger and close
+ dataJobExecutionsPage.openTypeFilter();
+ dataJobExecutionsPage.filterByType("manual");
+ dataJobExecutionsPage
+ .getDataGridExecTypeContainers("scheduled")
+ .should("have.length", 0);
+ dataJobExecutionsPage.filterByType("scheduled");
+ dataJobExecutionsPage.closeFilter();
+
+ // verify current URL has appended filters execution status: user_error and platform_error, trigger type: manual and scheduled, and sort by startTime descending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"startTime":-1}',
+ filter:
+ '{"status":"user_error,platform_error","type":"manual,scheduled"}',
+ },
+ });
+
+ // sort by exec ID ascending
+ dataJobExecutionsPage.sortByExecID();
+
+ // open exec ID filter
+ dataJobExecutionsPage.openIDFilter();
+ // type job name as filter value
+ dataJobExecutionsPage.typeToTextFilterInput(
+ longLivedFailingJobFixture.job_name,
+ );
+ // verify only cells that match the value are rendered
+ dataJobExecutionsPage
+ .getDataGridExecIDCells()
+ .then(($cells) => {
+ const foundCells = Array.from($cells).map((cell) =>
+ new RegExp(`^${longLivedFailingJobFixture.job_name}-\d+$`).test(
+ `${cell.innerText?.trim()}`,
+ ),
+ );
+
+ return foundCells.length;
+ })
+ .should("gt", 0);
+ // verify current URL has appended filters execution status: user_error and platform_error, trigger type: manual and scheduled, id: long_lived_job_name and sort by id ascending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"id":1}',
+ filter: `{"status":"user_error,platform_error","type":"manual,scheduled","id":"${longLivedFailingJobFixture.job_name}"}`,
+ },
+ });
+
+ // open exec start time filter and type generated filterValue and close
+ dataJobExecutionsPage.openExecStartFilter();
+ dataJobExecutionsPage
+ .generateExecStartFilterValue()
+ .then((filterValue) => {
+ // type generated filter value
+ dataJobExecutionsPage.typeToTextFilterInput(filterValue);
+
+ // verify only cells that match the value are rendered
+ dataJobExecutionsPage
+ .getDataGridExecStartCells()
+ .then(($cells) => {
+ const foundCells = Array.from($cells).map((cell) =>
+ new RegExp(`${filterValue}$`).test(
+ `${cell.innerText?.trim()}`,
+ ),
+ );
+
+ return foundCells.length;
+ })
+ .should("gt", 0);
+
+ // verify current URL has appended filters execution status: user_error and platform_error, trigger type: manual and scheduled, id: long_lived_job_name, startTime: ${filterValue} and sort by id ascending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"id":1}',
+ filter: `{"status":"user_error,platform_error","type":"manual,scheduled","id":"${longLivedFailingJobFixture.job_name}","startTime":"${filterValue}"}`,
+ },
});
- dataJobExecutionsPage.closeFilter();
-
- // open exec end time filter and type generated filterValue and close
- dataJobExecutionsPage.openExecEndFilter();
- dataJobExecutionsPage.generateExecEndFilterValue().then((filterValue) => {
- // type generated filter value
- dataJobExecutionsPage.typeToTextFilterInput(filterValue);
-
- // verify only cells that match the value are rendered
- dataJobExecutionsPage
- .getDataGridExecEndCells()
- .then(($cells) => {
- const foundCells = Array.from($cells).map((cell) => new RegExp(`${filterValue}$`).test(`${cell.innerText?.trim()}`));
-
- return foundCells.length;
- })
- .should('gt', 0);
-
- // verify current URL has appended filters execution status: user_error and platform_error, trigger type: manual and scheduled, id: long_lived_job_name, startTime: ${filterValue}, endTime: ${filterValue} and sort by id ascending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"id":1}',
- filter: `{"status":"user_error,platform_error","type":"manual,scheduled","id":"${longLivedFailingJobFixture.job_name}","startTime":"${filterValue}","endTime":"${filterValue}"}`
- }
- });
+ });
+ dataJobExecutionsPage.closeFilter();
+
+ // open exec end time filter and type generated filterValue and close
+ dataJobExecutionsPage.openExecEndFilter();
+ dataJobExecutionsPage
+ .generateExecEndFilterValue()
+ .then((filterValue) => {
+ // type generated filter value
+ dataJobExecutionsPage.typeToTextFilterInput(filterValue);
+
+ // verify only cells that match the value are rendered
+ dataJobExecutionsPage
+ .getDataGridExecEndCells()
+ .then(($cells) => {
+ const foundCells = Array.from($cells).map((cell) =>
+ new RegExp(`${filterValue}$`).test(
+ `${cell.innerText?.trim()}`,
+ ),
+ );
+
+ return foundCells.length;
+ })
+ .should("gt", 0);
+
+ // verify current URL has appended filters execution status: user_error and platform_error, trigger type: manual and scheduled, id: long_lived_job_name, startTime: ${filterValue}, endTime: ${filterValue} and sort by id ascending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"id":1}',
+ filter: `{"status":"user_error,platform_error","type":"manual,scheduled","id":"${longLivedFailingJobFixture.job_name}","startTime":"${filterValue}","endTime":"${filterValue}"}`,
+ },
});
- dataJobExecutionsPage.closeFilter();
-
- // extract current url for next test
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .then((urlNormalized) => {
- const pathSegment = urlNormalized.pathSegment;
- const queryParamsSerialized = Object.entries(urlNormalized.queryParams)
- .map((keyValuePair) => keyValuePair.join('='))
- .join('&');
- navigationUrlWithFiltersAndSort = `${pathSegment}?${queryParamsSerialized}`;
-
- cy.log(navigationUrlWithFiltersAndSort);
- console.log(navigationUrlWithFiltersAndSort);
- });
});
+ dataJobExecutionsPage.closeFilter();
+
+ // extract current url for next test
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .then((urlNormalized) => {
+ const pathSegment = urlNormalized.pathSegment;
+ const queryParamsSerialized = Object.entries(
+ urlNormalized.queryParams,
+ )
+ .map((keyValuePair) => keyValuePair.join("="))
+ .join("&");
+ navigationUrlWithFiltersAndSort = `${pathSegment}?${queryParamsSerialized}`;
+
+ cy.log(navigationUrlWithFiltersAndSort);
+ console.log(navigationUrlWithFiltersAndSort);
+ });
+ });
+
+ it("should verify URL navigation with filters and sort will prefill everything and filter accordingly", () => {
+ const dataJobExecutionsPage =
+ DataJobManageExecutionsPage.navigateToExecutionsWithUrl(
+ navigationUrlWithFiltersAndSort,
+ );
- it('should verify URL navigation with filters and sort will prefill everything and filter accordingly', () => {
- const dataJobExecutionsPage = DataJobManageExecutionsPage.navigateToExecutionsWithUrl(navigationUrlWithFiltersAndSort);
-
- // open status filter, verify then close
- dataJobExecutionsPage.openStatusFilter();
- dataJobExecutionsPage.getDataGridExecStatusFilterCheckboxesStatuses().should('deep.equal', [
- ['succeeded', false],
- ['platform_error', true],
- ['user_error', true],
- ['running', false],
- ['submitted', false],
- ['skipped', false],
- ['cancelled', false]
- ]);
- dataJobExecutionsPage.closeFilter();
-
- // open type filter, verify then close
- dataJobExecutionsPage.openTypeFilter();
- dataJobExecutionsPage.getDataGridExecTypeFilterCheckboxesStatuses().should('deep.equal', [
- ['manual', true],
- ['scheduled', true]
- ]);
- dataJobExecutionsPage.getDataGridExecTypeContainers('manual').should('have.length.gte', 0);
- dataJobExecutionsPage.getDataGridExecTypeContainers('scheduled').should('have.length.gte', 0);
- dataJobExecutionsPage.closeFilter();
-
- // verify sort by id ascending
- dataJobExecutionsPage.getDataGridExecIDHeader().should('exist').invoke('attr', 'aria-sort').should('eq', 'ascending');
- dataJobExecutionsPage
- .getDataGridExecIDCell(1)
- .invoke('text')
- .invoke('trim')
- .then((elText1) => {
- return dataJobExecutionsPage
- .getDataGridExecIDCell(2)
- .invoke('text')
- .invoke('trim')
- .then((elText2) => {
- return elText2 > elText1;
- });
- })
- .should('be.true');
-
- // open id filter, verify then close
- dataJobExecutionsPage.openIDFilter();
- dataJobExecutionsPage.getDataGridInputFilter().should('exist').should('have.value', longLivedFailingJobFixture.job_name);
- // verify only cells that match the value are rendered
- dataJobExecutionsPage
- .getDataGridExecIDCells()
- .then(($cells) => {
- const foundCells = Array.from($cells).map((cell) => new RegExp(`^${longLivedFailingJobFixture.job_name}-\d+$`).test(`${cell.innerText?.trim()}`));
-
- return foundCells.length;
- })
- .should('gt', 0);
- dataJobExecutionsPage.closeFilter();
-
- // open exec start time filter, verify then close
- dataJobExecutionsPage.openExecStartFilter();
- dataJobExecutionsPage.generateExecStartFilterValue().then((filterValue) => {
- // verify generated value prefilled in input field
- dataJobExecutionsPage.getDataGridInputFilter().should('exist').should('have.value', filterValue);
-
- // verify only cells that match the value are rendered
- dataJobExecutionsPage
- .getDataGridExecStartCells()
- .then(($cells) => {
- const foundCells = Array.from($cells).map((cell) => new RegExp(`${filterValue}$`).test(`${cell.innerText?.trim()}`));
-
- return foundCells.length;
- })
- .should('gt', 0);
+ // open status filter, verify then close
+ dataJobExecutionsPage.openStatusFilter();
+ dataJobExecutionsPage
+ .getDataGridExecStatusFilterCheckboxesStatuses()
+ .should("deep.equal", [
+ ["succeeded", false],
+ ["platform_error", true],
+ ["user_error", true],
+ ["running", false],
+ ["submitted", false],
+ ["skipped", false],
+ ["cancelled", false],
+ ]);
+ dataJobExecutionsPage.closeFilter();
+
+ // open type filter, verify then close
+ dataJobExecutionsPage.openTypeFilter();
+ dataJobExecutionsPage
+ .getDataGridExecTypeFilterCheckboxesStatuses()
+ .should("deep.equal", [
+ ["manual", true],
+ ["scheduled", true],
+ ]);
+ dataJobExecutionsPage
+ .getDataGridExecTypeContainers("manual")
+ .should("have.length.gte", 0);
+ dataJobExecutionsPage
+ .getDataGridExecTypeContainers("scheduled")
+ .should("have.length.gte", 0);
+ dataJobExecutionsPage.closeFilter();
+
+ // verify sort by id ascending
+ dataJobExecutionsPage
+ .getDataGridExecIDHeader()
+ .should("exist")
+ .invoke("attr", "aria-sort")
+ .should("eq", "ascending");
+ dataJobExecutionsPage
+ .getDataGridExecIDCell(1)
+ .invoke("text")
+ .invoke("trim")
+ .then((elText1) => {
+ return dataJobExecutionsPage
+ .getDataGridExecIDCell(2)
+ .invoke("text")
+ .invoke("trim")
+ .then((elText2) => {
+ return elText2 > elText1;
});
- dataJobExecutionsPage.closeFilter();
-
- // open exec end time filter, verify then close
- dataJobExecutionsPage.openExecEndFilter();
- dataJobExecutionsPage.generateExecEndFilterValue().then((filterValue) => {
- // verify generated value prefilled in input field
- dataJobExecutionsPage.getDataGridInputFilter().should('exist').should('have.value', filterValue);
-
- // verify only cells that match the value are rendered
- dataJobExecutionsPage
- .getDataGridExecEndCells()
- .then(($cells) => {
- const foundCells = Array.from($cells).map((cell) => new RegExp(`${filterValue}$`).test(`${cell.innerText?.trim()}`));
-
- return foundCells.length;
- })
- .should('gt', 0);
-
- // verify current URL has appended filters execution status: user_error and platform_error, trigger type: manual and scheduled, id: long_lived_job_name, startTime: ${filterValue}, endTime: ${filterValue} and sort by id ascending
- dataJobExecutionsPage
- .getCurrentUrlNormalized({
- includePathSegment: true,
- includeQueryString: true,
- decodeQueryString: true
- })
- .should('deep.equal', {
- pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
- queryParams: {
- sort: '{"id":1}',
- filter: `{"status":"user_error,platform_error","type":"manual,scheduled","startTime":"${filterValue}","endTime":"${filterValue}","id":"${longLivedFailingJobFixture.job_name}"}`
- }
- });
+ })
+ .should("be.true");
+
+ // open id filter, verify then close
+ dataJobExecutionsPage.openIDFilter();
+ dataJobExecutionsPage
+ .getDataGridInputFilter()
+ .should("exist")
+ .should("have.value", longLivedFailingJobFixture.job_name);
+ // verify only cells that match the value are rendered
+ dataJobExecutionsPage
+ .getDataGridExecIDCells()
+ .then(($cells) => {
+ const foundCells = Array.from($cells).map((cell) =>
+ new RegExp(`^${longLivedFailingJobFixture.job_name}-\d+$`).test(
+ `${cell.innerText?.trim()}`,
+ ),
+ );
+
+ return foundCells.length;
+ })
+ .should("gt", 0);
+ dataJobExecutionsPage.closeFilter();
+
+ // open exec start time filter, verify then close
+ dataJobExecutionsPage.openExecStartFilter();
+ dataJobExecutionsPage
+ .generateExecStartFilterValue()
+ .then((filterValue) => {
+ // verify generated value prefilled in input field
+ dataJobExecutionsPage
+ .getDataGridInputFilter()
+ .should("exist")
+ .should("have.value", filterValue);
+
+ // verify only cells that match the value are rendered
+ dataJobExecutionsPage
+ .getDataGridExecStartCells()
+ .then(($cells) => {
+ const foundCells = Array.from($cells).map((cell) =>
+ new RegExp(`${filterValue}$`).test(
+ `${cell.innerText?.trim()}`,
+ ),
+ );
+
+ return foundCells.length;
+ })
+ .should("gt", 0);
+ });
+ dataJobExecutionsPage.closeFilter();
+
+ // open exec end time filter, verify then close
+ dataJobExecutionsPage.openExecEndFilter();
+ dataJobExecutionsPage
+ .generateExecEndFilterValue()
+ .then((filterValue) => {
+ // verify generated value prefilled in input field
+ dataJobExecutionsPage
+ .getDataGridInputFilter()
+ .should("exist")
+ .should("have.value", filterValue);
+
+ // verify only cells that match the value are rendered
+ dataJobExecutionsPage
+ .getDataGridExecEndCells()
+ .then(($cells) => {
+ const foundCells = Array.from($cells).map((cell) =>
+ new RegExp(`${filterValue}$`).test(
+ `${cell.innerText?.trim()}`,
+ ),
+ );
+
+ return foundCells.length;
+ })
+ .should("gt", 0);
+
+ // verify current URL has appended filters execution status: user_error and platform_error, trigger type: manual and scheduled, id: long_lived_job_name, startTime: ${filterValue}, endTime: ${filterValue} and sort by id ascending
+ dataJobExecutionsPage
+ .getCurrentUrlNormalized({
+ includePathSegment: true,
+ includeQueryString: true,
+ decodeQueryString: true,
+ })
+ .should("deep.equal", {
+ pathSegment: `/manage/data-jobs/${longLivedFailingJobFixture.team}/${longLivedFailingJobFixture.job_name}/executions`,
+ queryParams: {
+ sort: '{"id":1}',
+ filter: `{"status":"user_error,platform_error","type":"manual,scheduled","startTime":"${filterValue}","endTime":"${filterValue}","id":"${longLivedFailingJobFixture.job_name}"}`,
+ },
});
- dataJobExecutionsPage.closeFilter();
});
+ dataJobExecutionsPage.closeFilter();
});
+ });
});
-});
+ },
+);
diff --git a/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/router/router.spec.js b/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/router/router.spec.js
index 445f3e31d6..141735821d 100644
--- a/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/router/router.spec.js
+++ b/projects/frontend/data-pipelines/gui/e2e/integration/frontend-tests/router/router.spec.js
@@ -5,20 +5,22 @@
///
-import { BasePagePO } from '../../../support/pages/base/base-page.po';
+import { BasePagePO } from "../../../support/pages/base/base-page.po";
-describe('Routing for pages', () => {
- describe('smoke', { tags: ['@smoke'] }, () => {
- it('navigates to get-started page when explore page route is ignored', () => {
- BasePagePO.executeCypressCommand('appConfigInterceptorDisableExploreRoute');
- // wait for login
- BasePagePO.wireUserSession();
- BasePagePO.initInterceptors();
- BasePagePO.navigateTo();
- // go to explore page url
- cy.visit('/explore/data-jobs');
- // should navigate to get-started instead
- cy.location().should((l) => expect(l.pathname).to.equal('/get-started'));
- });
+describe("Routing for pages", () => {
+ describe("smoke", { tags: ["@smoke"] }, () => {
+ it("navigates to get-started page when explore page route is ignored", () => {
+ BasePagePO.executeCypressCommand(
+ "appConfigInterceptorDisableExploreRoute",
+ );
+ // wait for login
+ BasePagePO.wireUserSession();
+ BasePagePO.initInterceptors();
+ BasePagePO.navigateTo();
+ // go to explore page url
+ cy.visit("/explore/data-jobs");
+ // should navigate to get-started instead
+ cy.location().should((l) => expect(l.pathname).to.equal("/get-started"));
});
+ });
});
diff --git a/projects/frontend/data-pipelines/gui/e2e/integration/quickstart-operability/quickstart.spec.js b/projects/frontend/data-pipelines/gui/e2e/integration/quickstart-operability/quickstart.spec.js
index 17fa3e1247..5f70fef349 100644
--- a/projects/frontend/data-pipelines/gui/e2e/integration/quickstart-operability/quickstart.spec.js
+++ b/projects/frontend/data-pipelines/gui/e2e/integration/quickstart-operability/quickstart.spec.js
@@ -5,28 +5,42 @@
///
-import { GetStartedPagePO } from '../../support/pages/get-started/get-started-page.po';
-import { DataJobsManagePage } from '../../support/pages/manage/data-jobs/data-jobs.po';
-import { BasePagePO } from '../../support/pages/base/base-page.po';
+import { GetStartedPagePO } from "../../support/pages/get-started/get-started-page.po";
+import { DataJobsManagePage } from "../../support/pages/manage/data-jobs/data-jobs.po";
+import { BasePagePO } from "../../support/pages/base/base-page.po";
-describe('Check if quickstart-vdk frontend is operational', () => {
- describe('smoke', { tags: ['@smoke'] }, () => {
- it('navigates to root page and the page loads correctly', () => {
- const getStartedPage = BasePagePO.navigateToNoBootstrap();
- getStartedPage.getPageTitle().invoke('text').invoke('trim').should('eq', 'Get Started with Data Pipelines');
- });
+describe("Check if quickstart-vdk frontend is operational", () => {
+ describe("smoke", { tags: ["@smoke"] }, () => {
+ it("navigates to root page and the page loads correctly", () => {
+ const getStartedPage = BasePagePO.navigateToNoBootstrap();
+ getStartedPage
+ .getPageTitle()
+ .invoke("text")
+ .invoke("trim")
+ .should("eq", "Get Started with Data Pipelines");
+ });
- it('navigates to get-started page and the page loads correctly', () => {
- const getStartedPage = GetStartedPagePO.navigateToNoBootstrap();
- getStartedPage.getPageTitle().invoke('text').invoke('trim').should('eq', 'Get Started with Data Pipelines');
- });
+ it("navigates to get-started page and the page loads correctly", () => {
+ const getStartedPage = GetStartedPagePO.navigateToNoBootstrap();
+ getStartedPage
+ .getPageTitle()
+ .invoke("text")
+ .invoke("trim")
+ .should("eq", "Get Started with Data Pipelines");
+ });
- it('navigates to manage page and the page loads correctly', () => {
- const dataJobsManagePage = DataJobsManagePage.navigateToNoBootstrap();
+ it("navigates to manage page and the page loads correctly", () => {
+ const dataJobsManagePage = DataJobsManagePage.navigateToNoBootstrap();
- dataJobsManagePage.getPageTitle().scrollIntoView().should('be.visible').invoke('text').invoke('trim').should('eq', 'Manage Data Jobs');
+ dataJobsManagePage
+ .getPageTitle()
+ .scrollIntoView()
+ .should("be.visible")
+ .invoke("text")
+ .invoke("trim")
+ .should("eq", "Manage Data Jobs");
- dataJobsManagePage.getDataGrid().scrollIntoView().should('be.visible');
- });
+ dataJobsManagePage.getDataGrid().scrollIntoView().should("be.visible");
});
+ });
});
diff --git a/projects/frontend/data-pipelines/gui/e2e/plugins/helpers/authentication-helpers.plugins.js b/projects/frontend/data-pipelines/gui/e2e/plugins/helpers/authentication-helpers.plugins.js
index 791298fd5c..4938765cec 100644
--- a/projects/frontend/data-pipelines/gui/e2e/plugins/helpers/authentication-helpers.plugins.js
+++ b/projects/frontend/data-pipelines/gui/e2e/plugins/helpers/authentication-helpers.plugins.js
@@ -6,28 +6,28 @@
let ACCESS_TOKEN;
const getAccessTokenSynchronous = () => {
- return ACCESS_TOKEN;
+ return ACCESS_TOKEN;
};
const setAccessTokenSynchronous = (token) => {
- ACCESS_TOKEN = token;
+ ACCESS_TOKEN = token;
- return ACCESS_TOKEN;
+ return ACCESS_TOKEN;
};
const getAccessTokenAsynchronous = () => {
- return Promise.resolve(ACCESS_TOKEN);
+ return Promise.resolve(ACCESS_TOKEN);
};
const setAccessTokenAsynchronous = (token) => {
- ACCESS_TOKEN = token;
+ ACCESS_TOKEN = token;
- return Promise.resolve(ACCESS_TOKEN);
+ return Promise.resolve(ACCESS_TOKEN);
};
module.exports = {
- getAccessTokenSynchronous,
- setAccessTokenSynchronous,
- getAccessTokenAsynchronous,
- setAccessTokenAsynchronous
+ getAccessTokenSynchronous,
+ setAccessTokenSynchronous,
+ getAccessTokenAsynchronous,
+ setAccessTokenAsynchronous,
};
diff --git a/projects/frontend/data-pipelines/gui/e2e/plugins/helpers/http-helpers.plugins.js b/projects/frontend/data-pipelines/gui/e2e/plugins/helpers/http-helpers.plugins.js
index d1b18d1835..b0c4c3905c 100644
--- a/projects/frontend/data-pipelines/gui/e2e/plugins/helpers/http-helpers.plugins.js
+++ b/projects/frontend/data-pipelines/gui/e2e/plugins/helpers/http-helpers.plugins.js
@@ -3,15 +3,17 @@
* SPDX-License-Identifier: Apache-2.0
*/
-const { default: axios } = require('axios');
+const { default: axios } = require("axios");
-const { cloneDeep } = require('lodash');
+const { cloneDeep } = require("lodash");
-const { Logger } = require('./logger-helpers.plugins');
+const { Logger } = require("./logger-helpers.plugins");
-const { trimArraysToNElements } = require('./util-helpers.plugins');
+const { trimArraysToNElements } = require("./util-helpers.plugins");
-const { getAccessTokenSynchronous } = require('./authentication-helpers.plugins');
+const {
+ getAccessTokenSynchronous,
+} = require("./authentication-helpers.plugins");
/**
* ** Create Http Get request.
@@ -22,30 +24,37 @@ const { getAccessTokenSynchronous } = require('./authentication-helpers.plugins'
* @returns {Promise>}
*/
const httpGetReq = (url, headers = {}, auth = undefined) => {
- const startTime = new Date();
-
- Logger.debug(`HTTP Get request for Url =>`, url);
- Logger.profiling(`Start time: ${startTime.toISOString()}`);
-
- return axios
- .request({
- url,
- method: 'get',
- headers: {
- authorization: `Bearer ${getAccessTokenSynchronous()}`,
- ...headers
- },
- validateStatus: () => true,
- auth
- })
- .then((response) => {
- const endTime = new Date();
-
- Logger.debug(`HTTP Get response from Url with Body`, url, _filterResponseDataForDebug(response));
- Logger.profiling(`End time: ${endTime.toISOString()};`, `Duration: ${(endTime - startTime) / 1000}s`);
-
- return _throttle(response);
- });
+ const startTime = new Date();
+
+ Logger.debug(`HTTP Get request for Url =>`, url);
+ Logger.profiling(`Start time: ${startTime.toISOString()}`);
+
+ return axios
+ .request({
+ url,
+ method: "get",
+ headers: {
+ authorization: `Bearer ${getAccessTokenSynchronous()}`,
+ ...headers,
+ },
+ validateStatus: () => true,
+ auth,
+ })
+ .then((response) => {
+ const endTime = new Date();
+
+ Logger.debug(
+ `HTTP Get response from Url with Body`,
+ url,
+ _filterResponseDataForDebug(response),
+ );
+ Logger.profiling(
+ `End time: ${endTime.toISOString()};`,
+ `Duration: ${(endTime - startTime) / 1000}s`,
+ );
+
+ return _throttle(response);
+ });
};
/**
@@ -57,30 +66,37 @@ const httpGetReq = (url, headers = {}, auth = undefined) => {
* @returns {Promise>}
*/
const httpPostReq = (url, body, headers = {}) => {
- const startTime = new Date();
-
- Logger.debug(`HTTP Post request to Url with Body =>`, url, body);
- Logger.profiling(`Start time: ${startTime.toISOString()}`);
-
- return axios
- .request({
- url: url,
- method: 'post',
- headers: {
- authorization: `Bearer ${getAccessTokenSynchronous()}`,
- ...headers
- },
- data: body,
- validateStatus: () => true
- })
- .then((response) => {
- const endTime = new Date();
-
- Logger.debug(`HTTP Post response from Url with Body`, url, _filterResponseDataForDebug(response));
- Logger.profiling(`End time: ${endTime.toISOString()};`, `Duration: ${(endTime - startTime) / 1000}s`);
-
- return _throttle(response);
- });
+ const startTime = new Date();
+
+ Logger.debug(`HTTP Post request to Url with Body =>`, url, body);
+ Logger.profiling(`Start time: ${startTime.toISOString()}`);
+
+ return axios
+ .request({
+ url: url,
+ method: "post",
+ headers: {
+ authorization: `Bearer ${getAccessTokenSynchronous()}`,
+ ...headers,
+ },
+ data: body,
+ validateStatus: () => true,
+ })
+ .then((response) => {
+ const endTime = new Date();
+
+ Logger.debug(
+ `HTTP Post response from Url with Body`,
+ url,
+ _filterResponseDataForDebug(response),
+ );
+ Logger.profiling(
+ `End time: ${endTime.toISOString()};`,
+ `Duration: ${(endTime - startTime) / 1000}s`,
+ );
+
+ return _throttle(response);
+ });
};
/**
@@ -92,30 +108,37 @@ const httpPostReq = (url, body, headers = {}) => {
* @returns {Promise>}
*/
const httpPatchReq = (url, body, headers = {}) => {
- const startTime = new Date();
-
- Logger.debug(`HTTP Patch request to Url with Body =>`, url, body);
- Logger.profiling(`Start time: ${startTime.toISOString()}`);
-
- return axios
- .request({
- url: url,
- method: 'patch',
- headers: {
- authorization: `Bearer ${getAccessTokenSynchronous()}`,
- ...headers
- },
- data: body,
- validateStatus: () => true
- })
- .then((response) => {
- const endTime = new Date();
-
- Logger.debug(`HTTP Patch response from Url with Body`, url, _filterResponseDataForDebug(response));
- Logger.profiling(`End time: ${endTime.toISOString()};`, `Duration: ${(endTime - startTime) / 1000}s`);
-
- return _throttle(response);
- });
+ const startTime = new Date();
+
+ Logger.debug(`HTTP Patch request to Url with Body =>`, url, body);
+ Logger.profiling(`Start time: ${startTime.toISOString()}`);
+
+ return axios
+ .request({
+ url: url,
+ method: "patch",
+ headers: {
+ authorization: `Bearer ${getAccessTokenSynchronous()}`,
+ ...headers,
+ },
+ data: body,
+ validateStatus: () => true,
+ })
+ .then((response) => {
+ const endTime = new Date();
+
+ Logger.debug(
+ `HTTP Patch response from Url with Body`,
+ url,
+ _filterResponseDataForDebug(response),
+ );
+ Logger.profiling(
+ `End time: ${endTime.toISOString()};`,
+ `Duration: ${(endTime - startTime) / 1000}s`,
+ );
+
+ return _throttle(response);
+ });
};
/**
@@ -127,30 +150,37 @@ const httpPatchReq = (url, body, headers = {}) => {
* @returns {Promise>}
*/
const httpPutReq = (url, body, headers = {}) => {
- const startTime = new Date();
-
- Logger.debug(`HTTP Put request to Url with Body =>`, url, body);
- Logger.profiling(`Start time: ${startTime.toISOString()}`);
-
- return axios
- .request({
- url: url,
- method: 'put',
- headers: {
- authorization: `Bearer ${getAccessTokenSynchronous()}`,
- ...headers
- },
- data: body,
- validateStatus: () => true
- })
- .then((response) => {
- const endTime = new Date();
-
- Logger.debug(`HTTP Put response from Url with Body`, url, _filterResponseDataForDebug(response));
- Logger.profiling(`End time: ${endTime.toISOString()};`, `Duration: ${(endTime - startTime) / 1000}s`);
-
- return _throttle(response);
- });
+ const startTime = new Date();
+
+ Logger.debug(`HTTP Put request to Url with Body =>`, url, body);
+ Logger.profiling(`Start time: ${startTime.toISOString()}`);
+
+ return axios
+ .request({
+ url: url,
+ method: "put",
+ headers: {
+ authorization: `Bearer ${getAccessTokenSynchronous()}`,
+ ...headers,
+ },
+ data: body,
+ validateStatus: () => true,
+ })
+ .then((response) => {
+ const endTime = new Date();
+
+ Logger.debug(
+ `HTTP Put response from Url with Body`,
+ url,
+ _filterResponseDataForDebug(response),
+ );
+ Logger.profiling(
+ `End time: ${endTime.toISOString()};`,
+ `Duration: ${(endTime - startTime) / 1000}s`,
+ );
+
+ return _throttle(response);
+ });
};
/**
@@ -161,29 +191,36 @@ const httpPutReq = (url, body, headers = {}) => {
* @returns {Promise>}
*/
const httpDeleteReq = (url, headers = {}) => {
- const startTime = new Date();
-
- Logger.debug(`HTTP Delete request for Url =>`, url);
- Logger.profiling(`Start time: ${startTime.toISOString()}`);
-
- return axios
- .request({
- url: url,
- method: 'delete',
- headers: {
- authorization: `Bearer ${getAccessTokenSynchronous()}`,
- ...headers
- },
- validateStatus: () => true
- })
- .then((response) => {
- const endTime = new Date();
-
- Logger.debug(`HTTP Delete response from Url with Body`, url, _filterResponseDataForDebug(response));
- Logger.profiling(`End time: ${endTime.toISOString()};`, `Duration: ${(endTime - startTime) / 1000}s`);
-
- return _throttle(response);
- });
+ const startTime = new Date();
+
+ Logger.debug(`HTTP Delete request for Url =>`, url);
+ Logger.profiling(`Start time: ${startTime.toISOString()}`);
+
+ return axios
+ .request({
+ url: url,
+ method: "delete",
+ headers: {
+ authorization: `Bearer ${getAccessTokenSynchronous()}`,
+ ...headers,
+ },
+ validateStatus: () => true,
+ })
+ .then((response) => {
+ const endTime = new Date();
+
+ Logger.debug(
+ `HTTP Delete response from Url with Body`,
+ url,
+ _filterResponseDataForDebug(response),
+ );
+ Logger.profiling(
+ `End time: ${endTime.toISOString()};`,
+ `Duration: ${(endTime - startTime) / 1000}s`,
+ );
+
+ return _throttle(response);
+ });
};
/**
@@ -194,25 +231,25 @@ const httpDeleteReq = (url, headers = {}) => {
* @private
*/
const _filterResponseDataForDebug = (response) => {
- return {
- status: response.status,
- statusText: response.statusText,
- headers: {
- ...response.headers,
- authorization: '... removed from logs ...'
- },
- config: {
- timeout: response.config.timeout,
- headers: {
- ...response.config.headers,
- authorization: '... removed from logs ...'
- },
- url: response.config.url,
- method: response.config.method,
- data: response.config.data
- },
- data: trimArraysToNElements(cloneDeep(response.data), 5)
- };
+ return {
+ status: response.status,
+ statusText: response.statusText,
+ headers: {
+ ...response.headers,
+ authorization: "... removed from logs ...",
+ },
+ config: {
+ timeout: response.config.timeout,
+ headers: {
+ ...response.config.headers,
+ authorization: "... removed from logs ...",
+ },
+ url: response.config.url,
+ method: response.config.method,
+ data: response.config.data,
+ },
+ data: trimArraysToNElements(cloneDeep(response.data), 5),
+ };
};
/**
@@ -223,12 +260,12 @@ const _filterResponseDataForDebug = (response) => {
* @private
*/
const _throttle = (response) => {
- return new Promise((resolve) => {
- resolve(response); // Comment this line and uncomment bellow code if you want to test throttling in plugins api execution
- // setTimeout(() => {
- // resolve(response);
- // }, _randomNumberBetween(2, 10) * 1000);
- });
+ return new Promise((resolve) => {
+ resolve(response); // Comment this line and uncomment bellow code if you want to test throttling in plugins api execution
+ // setTimeout(() => {
+ // resolve(response);
+ // }, _randomNumberBetween(2, 10) * 1000);
+ });
};
/**
@@ -240,16 +277,16 @@ const _throttle = (response) => {
* @private
*/
const _randomNumberBetween = (minBoundary, maxBoundary) => {
- const _min = Math.ceil(minBoundary);
- const _max = Math.ceil(maxBoundary);
+ const _min = Math.ceil(minBoundary);
+ const _max = Math.ceil(maxBoundary);
- return Math.floor(Math.random() * (_max - _min + 1) + _min);
+ return Math.floor(Math.random() * (_max - _min + 1) + _min);
};
module.exports = {
- httpGetReq,
- httpPostReq,
- httpPatchReq,
- httpPutReq,
- httpDeleteReq
+ httpGetReq,
+ httpPostReq,
+ httpPatchReq,
+ httpPutReq,
+ httpDeleteReq,
};
diff --git a/projects/frontend/data-pipelines/gui/e2e/plugins/helpers/job-helpers.plugins.js b/projects/frontend/data-pipelines/gui/e2e/plugins/helpers/job-helpers.plugins.js
index d9cd33e559..b68694f5ba 100644
--- a/projects/frontend/data-pipelines/gui/e2e/plugins/helpers/job-helpers.plugins.js
+++ b/projects/frontend/data-pipelines/gui/e2e/plugins/helpers/job-helpers.plugins.js
@@ -3,14 +3,19 @@
* SPDX-License-Identifier: Apache-2.0
*/
-const fs = require('fs');
-const path = require('path');
+const fs = require("fs");
+const path = require("path");
-const { Logger } = require('./logger-helpers.plugins');
+const { Logger } = require("./logger-helpers.plugins");
-const { applyGlobalEnvSettings } = require('./util-helpers.plugins');
+const { applyGlobalEnvSettings } = require("./util-helpers.plugins");
-const { httpDeleteReq, httpGetReq, httpPostReq, httpPatchReq } = require('./http-helpers.plugins');
+const {
+ httpDeleteReq,
+ httpGetReq,
+ httpPostReq,
+ httpPatchReq,
+} = require("./http-helpers.plugins");
/**
* ** Create and Deploy Data jobs if they don't exist.
@@ -29,144 +34,187 @@ const { httpDeleteReq, httpGetReq, httpPostReq, httpPatchReq } = require('./http
* @returns {Promise}
*/
const createDeployJobs = (taskConfig, config) => {
- const startTime = new Date();
-
- Logger.info('Trying to load Data jobs fixtures and binaries.');
- Logger.profiling(`Start time: ${startTime.toISOString()}`);
-
- return (
- _loadFixturesValuesAndBinariesPaths(taskConfig.relativePathToFixtures)
- .then((commands) => {
- return Promise.all(
- // Send multiple parallel stream for Data jobs resolution
- commands.map((command, index) => {
- Logger.debug(`Data job fixture =>`, command.jobFixture);
-
- return (
- Promise
- // Pass command down the stream
- .resolve({ ...command, index })
- // Send requests to get Data job
- .then((prevCommand) => {
- return _getDataJobDeployments(prevCommand.jobFixture, config).then((response) => {
- return {
- ...prevCommand,
- response
- };
- });
- })
- // Check what is the state of requested Job, if it's deployed, or exist but not deployed, or doesn't exist at all
- .then((prevCommand) => {
- const jobFixture = prevCommand.jobFixture;
- const jobName = jobFixture.job_name;
- const httpResponse = prevCommand.response;
-
- let nextAction = 'done';
-
- if (httpResponse.status === 200 && httpResponse.data.length > 0) {
- Logger.info(`Data job "${jobName}" is already existing, therefore skipping creation and deployment.`);
- } else if (httpResponse.status === 200 && httpResponse.data.length === 0) {
- Logger.info(`Data job "${jobName}" exists, but it is not deployed. Will start deploying...`);
- nextAction = 'deploy';
- } else if (httpResponse.status === 404) {
- Logger.info(`Data job "${jobName}" not found. Will start creating...`);
- nextAction = 'create';
- }
-
- return {
- ...prevCommand,
- nextAction
- };
- })
- // Send request to create Job if its doesn't exist, otherwise pass execution to the next step
- .then((prevCommand) => {
- const currentAction = prevCommand.nextAction;
- const jobFixture = prevCommand.jobFixture;
- const jobName = jobFixture.job_name;
-
- if (currentAction === 'create') {
- return _createDataJob(jobFixture, config).then((response) => {
- if (response.status === 201) {
- return {
- ...prevCommand,
- nextAction: 'deploy'
- };
- } else {
- Logger.error(`Failed to create Data job "${jobName}"`);
-
- throw new Error(`Failed to create Data job "${jobName}"`);
- }
- });
- }
-
- return {
- ...prevCommand
- };
- })
- // Send request to deploy Job if it was created on previous step
- .then((prevCommandOuter) => {
- const currentAction = prevCommandOuter.nextAction;
- const jobFixture = prevCommandOuter.jobFixture;
- const pathToZipFile = prevCommandOuter.pathToZipFile;
- const jobName = jobFixture.job_name;
-
- if (currentAction === 'deploy') {
- if (!pathToZipFile) {
- Logger.info(`Data job "${jobName}" doesn't have path to job zip file, therefore skipping deployment.`);
- } else {
- Logger.debug(`Loading Job Zip binary located on =>`, pathToZipFile);
-
- let jobZipFile;
-
- try {
- jobZipFile = fs.readFileSync(pathToZipFile, { encoding: 'base64' });
- } catch (error) {
- Logger.error(`Cannot read file located on =>`, pathToZipFile);
-
- throw error;
- }
-
- return new Promise((resolve) => {
- setTimeout(() => resolve(prevCommandOuter), prevCommandOuter.index * 2000 + 250);
- }).then((prevCommandInner) => {
- return _deployDataJob(jobFixture, jobZipFile, config).then((result) => {
- return {
- ...prevCommandInner,
- ...result
- };
- });
- });
- }
- }
-
- return {
- ...prevCommandOuter,
- code: 0
- };
- })
- // Final step to validate if everything is OK
- .then((prevCommand) => {
- if (prevCommand.code === 0) {
- return true;
- }
-
- const jobFixture = prevCommand.jobFixture;
- const jobName = jobFixture.job_name;
-
- Logger.error(`Failed to create/deploy Data job "${jobName}"`);
-
- throw new Error(`Failed to create/deploy Data job "${jobName}".`);
- })
+ const startTime = new Date();
+
+ Logger.info("Trying to load Data jobs fixtures and binaries.");
+ Logger.profiling(`Start time: ${startTime.toISOString()}`);
+
+ return (
+ _loadFixturesValuesAndBinariesPaths(taskConfig.relativePathToFixtures)
+ .then((commands) => {
+ return Promise.all(
+ // Send multiple parallel stream for Data jobs resolution
+ commands.map((command, index) => {
+ Logger.debug(`Data job fixture =>`, command.jobFixture);
+
+ return (
+ Promise
+ // Pass command down the stream
+ .resolve({ ...command, index })
+ // Send requests to get Data job
+ .then((prevCommand) => {
+ return _getDataJobDeployments(
+ prevCommand.jobFixture,
+ config,
+ ).then((response) => {
+ return {
+ ...prevCommand,
+ response,
+ };
+ });
+ })
+ // Check what is the state of requested Job, if it's deployed, or exist but not deployed, or doesn't exist at all
+ .then((prevCommand) => {
+ const jobFixture = prevCommand.jobFixture;
+ const jobName = jobFixture.job_name;
+ const httpResponse = prevCommand.response;
+
+ let nextAction = "done";
+
+ if (
+ httpResponse.status === 200 &&
+ httpResponse.data.length > 0
+ ) {
+ Logger.info(
+ `Data job "${jobName}" is already existing, therefore skipping creation and deployment.`,
+ );
+ } else if (
+ httpResponse.status === 200 &&
+ httpResponse.data.length === 0
+ ) {
+ Logger.info(
+ `Data job "${jobName}" exists, but it is not deployed. Will start deploying...`,
+ );
+ nextAction = "deploy";
+ } else if (httpResponse.status === 404) {
+ Logger.info(
+ `Data job "${jobName}" not found. Will start creating...`,
+ );
+ nextAction = "create";
+ }
+
+ return {
+ ...prevCommand,
+ nextAction,
+ };
+ })
+ // Send request to create Job if its doesn't exist, otherwise pass execution to the next step
+ .then((prevCommand) => {
+ const currentAction = prevCommand.nextAction;
+ const jobFixture = prevCommand.jobFixture;
+ const jobName = jobFixture.job_name;
+
+ if (currentAction === "create") {
+ return _createDataJob(jobFixture, config).then(
+ (response) => {
+ if (response.status === 201) {
+ return {
+ ...prevCommand,
+ nextAction: "deploy",
+ };
+ } else {
+ Logger.error(
+ `Failed to create Data job "${jobName}"`,
+ );
+
+ throw new Error(
+ `Failed to create Data job "${jobName}"`,
+ );
+ }
+ },
+ );
+ }
+
+ return {
+ ...prevCommand,
+ };
+ })
+ // Send request to deploy Job if it was created on previous step
+ .then((prevCommandOuter) => {
+ const currentAction = prevCommandOuter.nextAction;
+ const jobFixture = prevCommandOuter.jobFixture;
+ const pathToZipFile = prevCommandOuter.pathToZipFile;
+ const jobName = jobFixture.job_name;
+
+ if (currentAction === "deploy") {
+ if (!pathToZipFile) {
+ Logger.info(
+ `Data job "${jobName}" doesn't have path to job zip file, therefore skipping deployment.`,
+ );
+ } else {
+ Logger.debug(
+ `Loading Job Zip binary located on =>`,
+ pathToZipFile,
+ );
+
+ let jobZipFile;
+
+ try {
+ jobZipFile = fs.readFileSync(pathToZipFile, {
+ encoding: "base64",
+ });
+ } catch (error) {
+ Logger.error(
+ `Cannot read file located on =>`,
+ pathToZipFile,
);
- })
- );
- })
- // Deployment to its end for all Jobs
- .finally(() => {
- const endTime = new Date();
- Logger.profiling(`End time: ${endTime.toISOString()};`, `Duration: ${(endTime - startTime) / 1000}s`);
- })
- );
+
+ throw error;
+ }
+
+ return new Promise((resolve) => {
+ setTimeout(
+ () => resolve(prevCommandOuter),
+ prevCommandOuter.index * 2000 + 250,
+ );
+ }).then((prevCommandInner) => {
+ return _deployDataJob(
+ jobFixture,
+ jobZipFile,
+ config,
+ ).then((result) => {
+ return {
+ ...prevCommandInner,
+ ...result,
+ };
+ });
+ });
+ }
+ }
+
+ return {
+ ...prevCommandOuter,
+ code: 0,
+ };
+ })
+ // Final step to validate if everything is OK
+ .then((prevCommand) => {
+ if (prevCommand.code === 0) {
+ return true;
+ }
+
+ const jobFixture = prevCommand.jobFixture;
+ const jobName = jobFixture.job_name;
+
+ Logger.error(`Failed to create/deploy Data job "${jobName}"`);
+
+ throw new Error(
+ `Failed to create/deploy Data job "${jobName}".`,
+ );
+ })
+ );
+ }),
+ );
+ })
+ // Deployment to its end for all Jobs
+ .finally(() => {
+ const endTime = new Date();
+ Logger.profiling(
+ `End time: ${endTime.toISOString()};`,
+ `Duration: ${(endTime - startTime) / 1000}s`,
+ );
+ })
+ );
};
/**
@@ -186,120 +234,158 @@ const createDeployJobs = (taskConfig, config) => {
* @returns {Promise}
*/
const provideDataJobsExecutions = (taskConfig, config) => {
- const startTime = new Date();
- const jobExecutionTimeout = 180000; // Wait up to 3 min per Job for execution to complete
-
- Logger.info(`Trying to provide executions for Data job fixtures`);
- Logger.profiling(`Start time: ${startTime.toISOString()}`);
-
- return (
- _loadFixturesValuesAndBinariesPaths(taskConfig.relativePathToFixtures)
- .then((commands) => {
- // Send requests to get data for all the Jobs
- return Promise.all(
- commands.map((command, index) => {
- Logger.debug(`Data job fixture =>`, command.jobFixture);
-
- const jobFixture = command.jobFixture;
- const jobName = jobFixture.job_name;
- const targetExecutions = taskConfig.relativePathToFixtures[index]?.executions ?? 2;
-
- Logger.info(`Trying to provide at least ${targetExecutions} executions for Data job ${jobName}`);
-
- // Pass the command down the stream with timeouts to avoid glitch on the server
- return (
- new Promise((resolve) => {
- setTimeout(() => resolve({ ...command }), index * 2150 + 350);
- })
- // Get Data job executions
- .then((prevCommandOuter) => {
- return _getDataJobExecutionsArray(prevCommandOuter.jobFixture, config).then((executions) => {
- Logger.info(`For Data job "${jobName}" found ${executions.length} executions, while target is ${targetExecutions}`);
-
- if (executions.length >= targetExecutions) {
- Logger.info(`For Data job "${jobName}" skipping serial execution, because expected number found`);
-
- if (executions.length > targetExecutions) {
- return {
- ...prevCommandOuter,
- executions,
- code: 0
- };
- }
-
- // Wait to finish if there is already executing Data job and continue
- return waitForDataJobExecutionToComplete(jobFixture, jobExecutionTimeout, config).then(() => {
- return {
- ...prevCommandOuter,
- executions,
- code: 0
- };
- });
- }
-
- // Wait to finish if there is already executing Data job and continue
- return (
- waitForDataJobExecutionToComplete(jobFixture, jobExecutionTimeout, config)
- .then(() => {
- return {
- ...prevCommandOuter,
- executions,
- code: 0
- };
- })
- // Get Data job last deployment
- .then((prevCommandInner) => {
- return _getJobLastDeployment(jobFixture, config).then((lastDeployment) => {
- return {
- ...prevCommandInner,
- lastDeployment,
- code: 0
- };
- });
- })
- // If last deployment found trigger execution for Data job
- .then((prevCommandInner) => {
- if (prevCommandInner.lastDeployment) {
- return _triggerExecutionForJob(jobFixture, jobExecutionTimeout, prevCommandInner.lastDeployment, targetExecutions - prevCommandInner.executions.length, config).then((result) => {
- return {
- ...prevCommandInner,
- ...result
- };
- });
- } else {
- Logger.error(`For Data job "${jobName}" last deployment was not found`);
- }
-
- return {
- ...prevCommandInner,
- code: 1
- };
- })
- );
- });
- })
- // Final step to validate if everything is OK
- .then((prevCommand) => {
- if (prevCommand.code === 0) {
- Logger.info(`Provided at least ${targetExecutions} executions for Data job fixtures`);
-
- return true;
- }
-
- Logger.error(`Failed to provide at least ${targetExecutions} for Data job "${jobName}"`);
-
- throw new Error(`Failed to provide at least ${targetExecutions} for Data job "${jobName}"`);
- })
- );
- })
- );
- })
- // Executions to its end for all Jobs
- .finally(() => {
- const endTime = new Date();
- Logger.profiling(`End time: ${endTime.toISOString()};`, `Duration: ${(endTime - startTime) / 1000}s`);
- })
- );
+ const startTime = new Date();
+ const jobExecutionTimeout = 180000; // Wait up to 3 min per Job for execution to complete
+
+ Logger.info(`Trying to provide executions for Data job fixtures`);
+ Logger.profiling(`Start time: ${startTime.toISOString()}`);
+
+ return (
+ _loadFixturesValuesAndBinariesPaths(taskConfig.relativePathToFixtures)
+ .then((commands) => {
+ // Send requests to get data for all the Jobs
+ return Promise.all(
+ commands.map((command, index) => {
+ Logger.debug(`Data job fixture =>`, command.jobFixture);
+
+ const jobFixture = command.jobFixture;
+ const jobName = jobFixture.job_name;
+ const targetExecutions =
+ taskConfig.relativePathToFixtures[index]?.executions ?? 2;
+
+ Logger.info(
+ `Trying to provide at least ${targetExecutions} executions for Data job ${jobName}`,
+ );
+
+ // Pass the command down the stream with timeouts to avoid glitch on the server
+ return (
+ new Promise((resolve) => {
+ setTimeout(() => resolve({ ...command }), index * 2150 + 350);
+ })
+ // Get Data job executions
+ .then((prevCommandOuter) => {
+ return _getDataJobExecutionsArray(
+ prevCommandOuter.jobFixture,
+ config,
+ ).then((executions) => {
+ Logger.info(
+ `For Data job "${jobName}" found ${executions.length} executions, while target is ${targetExecutions}`,
+ );
+
+ if (executions.length >= targetExecutions) {
+ Logger.info(
+ `For Data job "${jobName}" skipping serial execution, because expected number found`,
+ );
+
+ if (executions.length > targetExecutions) {
+ return {
+ ...prevCommandOuter,
+ executions,
+ code: 0,
+ };
+ }
+
+ // Wait to finish if there is already executing Data job and continue
+ return waitForDataJobExecutionToComplete(
+ jobFixture,
+ jobExecutionTimeout,
+ config,
+ ).then(() => {
+ return {
+ ...prevCommandOuter,
+ executions,
+ code: 0,
+ };
+ });
+ }
+
+ // Wait to finish if there is already executing Data job and continue
+ return (
+ waitForDataJobExecutionToComplete(
+ jobFixture,
+ jobExecutionTimeout,
+ config,
+ )
+ .then(() => {
+ return {
+ ...prevCommandOuter,
+ executions,
+ code: 0,
+ };
+ })
+ // Get Data job last deployment
+ .then((prevCommandInner) => {
+ return _getJobLastDeployment(jobFixture, config).then(
+ (lastDeployment) => {
+ return {
+ ...prevCommandInner,
+ lastDeployment,
+ code: 0,
+ };
+ },
+ );
+ })
+ // If last deployment found trigger execution for Data job
+ .then((prevCommandInner) => {
+ if (prevCommandInner.lastDeployment) {
+ return _triggerExecutionForJob(
+ jobFixture,
+ jobExecutionTimeout,
+ prevCommandInner.lastDeployment,
+ targetExecutions -
+ prevCommandInner.executions.length,
+ config,
+ ).then((result) => {
+ return {
+ ...prevCommandInner,
+ ...result,
+ };
+ });
+ } else {
+ Logger.error(
+ `For Data job "${jobName}" last deployment was not found`,
+ );
+ }
+
+ return {
+ ...prevCommandInner,
+ code: 1,
+ };
+ })
+ );
+ });
+ })
+ // Final step to validate if everything is OK
+ .then((prevCommand) => {
+ if (prevCommand.code === 0) {
+ Logger.info(
+ `Provided at least ${targetExecutions} executions for Data job fixtures`,
+ );
+
+ return true;
+ }
+
+ Logger.error(
+ `Failed to provide at least ${targetExecutions} for Data job "${jobName}"`,
+ );
+
+ throw new Error(
+ `Failed to provide at least ${targetExecutions} for Data job "${jobName}"`,
+ );
+ })
+ );
+ }),
+ );
+ })
+ // Executions to its end for all Jobs
+ .finally(() => {
+ const endTime = new Date();
+ Logger.profiling(
+ `End time: ${endTime.toISOString()};`,
+ `Duration: ${(endTime - startTime) / 1000}s`,
+ );
+ })
+ );
};
/**
@@ -319,49 +405,69 @@ const provideDataJobsExecutions = (taskConfig, config) => {
* @returns {Promise}
*/
const changeJobsStatusesFixtures = (taskConfig, config) => {
- const startTime = new Date();
-
- Logger.info(`Trying to disable Data Jobs for provided Data Jobs fixtures`);
- Logger.profiling(`Start time: ${startTime.toISOString()}`);
-
- return (
- _loadFixturesValuesAndBinariesPaths(taskConfig.relativePathToFixtures)
- .then((commands) => {
- const jobFixtures = commands.map((command) => applyGlobalEnvSettings(command.jobFixture));
-
- return Promise.all(
- jobFixtures.map((jobFixture) => {
- _getJobLastDeployment(jobFixture, config).then((lastDeployment) => {
- if (!lastDeployment || !lastDeployment.job_version) {
- Logger.error(`Deployment doesn't exist for Data Job "${jobFixture?.job_name}", skipping status change`);
-
- return false;
- }
-
- const deploymentHash = lastDeployment.job_version;
-
- return _updateDataJob(jobFixture.team, jobFixture.job_name, deploymentHash, { enabled: taskConfig.status }, config).then((updateResponse) => {
- if (updateResponse.status >= 200 && updateResponse.status < 300) {
- Logger.info(`Data Job "${jobFixture?.job_name}" status changed to "${taskConfig.status}"`);
-
- return true;
- }
+ const startTime = new Date();
+
+ Logger.info(`Trying to disable Data Jobs for provided Data Jobs fixtures`);
+ Logger.profiling(`Start time: ${startTime.toISOString()}`);
+
+ return (
+ _loadFixturesValuesAndBinariesPaths(taskConfig.relativePathToFixtures)
+ .then((commands) => {
+ const jobFixtures = commands.map((command) =>
+ applyGlobalEnvSettings(command.jobFixture),
+ );
+
+ return Promise.all(
+ jobFixtures.map((jobFixture) => {
+ _getJobLastDeployment(jobFixture, config).then((lastDeployment) => {
+ if (!lastDeployment || !lastDeployment.job_version) {
+ Logger.error(
+ `Deployment doesn't exist for Data Job "${jobFixture?.job_name}", skipping status change`,
+ );
- Logger.error(`Data Job "${jobFixture?.job_name}" failed status change to "${taskConfig.status}"`);
+ return false;
+ }
+
+ const deploymentHash = lastDeployment.job_version;
+
+ return _updateDataJob(
+ jobFixture.team,
+ jobFixture.job_name,
+ deploymentHash,
+ { enabled: taskConfig.status },
+ config,
+ ).then((updateResponse) => {
+ if (
+ updateResponse.status >= 200 &&
+ updateResponse.status < 300
+ ) {
+ Logger.info(
+ `Data Job "${jobFixture?.job_name}" status changed to "${taskConfig.status}"`,
+ );
+
+ return true;
+ }
- return false;
- });
- });
- })
+ Logger.error(
+ `Data Job "${jobFixture?.job_name}" failed status change to "${taskConfig.status}"`,
);
- })
- .then((responses) => responses.map((value) => !!value))
- // Status change to its end for all Jobs
- .finally(() => {
- const endTime = new Date();
- Logger.profiling(`End time: ${endTime.toISOString()};`, `Duration: ${(endTime - startTime) / 1000}s`);
- })
- );
+
+ return false;
+ });
+ });
+ }),
+ );
+ })
+ .then((responses) => responses.map((value) => !!value))
+ // Status change to its end for all Jobs
+ .finally(() => {
+ const endTime = new Date();
+ Logger.profiling(
+ `End time: ${endTime.toISOString()};`,
+ `Duration: ${(endTime - startTime) / 1000}s`,
+ );
+ })
+ );
};
/**
@@ -382,46 +488,51 @@ const changeJobsStatusesFixtures = (taskConfig, config) => {
* @returns {Promise}
*/
const deleteJobsFixtures = (taskConfig, config) => {
- const startTime = new Date();
-
- Logger.info(`Trying to delete Data Jobs for provided Data Jobs fixtures`);
- Logger.profiling(`Start time: ${startTime.toISOString()}`);
-
- return (
- _loadFixturesValuesAndBinariesPaths(taskConfig.relativePathToFixtures)
- .then((commands) => {
- const jobFixtures = commands.map((command) => command.jobFixture);
-
- // Send requests to delete data for fixtures
- return deleteJobs(jobFixtures, config).then((states) => {
- const successfulDeletion = [];
- const unsuccessfulDeletion = [];
-
- states.forEach((isSuccessful, index) => {
- if (isSuccessful) {
- successfulDeletion.push(jobFixtures[index].job_name);
- } else {
- unsuccessfulDeletion.push(jobFixtures[index].job_name);
- }
- });
+ const startTime = new Date();
+
+ Logger.info(`Trying to delete Data Jobs for provided Data Jobs fixtures`);
+ Logger.profiling(`Start time: ${startTime.toISOString()}`);
+
+ return (
+ _loadFixturesValuesAndBinariesPaths(taskConfig.relativePathToFixtures)
+ .then((commands) => {
+ const jobFixtures = commands.map((command) => command.jobFixture);
+
+ // Send requests to delete data for fixtures
+ return deleteJobs(jobFixtures, config).then((states) => {
+ const successfulDeletion = [];
+ const unsuccessfulDeletion = [];
+
+ states.forEach((isSuccessful, index) => {
+ if (isSuccessful) {
+ successfulDeletion.push(jobFixtures[index].job_name);
+ } else {
+ unsuccessfulDeletion.push(jobFixtures[index].job_name);
+ }
+ });
- if (successfulDeletion.length > 0) {
- Logger.info(`Deleted Data Jobs: ${successfulDeletion.toString()}`);
- }
+ if (successfulDeletion.length > 0) {
+ Logger.info(`Deleted Data Jobs: ${successfulDeletion.toString()}`);
+ }
- if (!taskConfig.optional && unsuccessfulDeletion.length > 0) {
- Logger.error(`Failed to delete Data Jobs: ${unsuccessfulDeletion.toString()}`);
- }
+ if (!taskConfig.optional && unsuccessfulDeletion.length > 0) {
+ Logger.error(
+ `Failed to delete Data Jobs: ${unsuccessfulDeletion.toString()}`,
+ );
+ }
- return true;
- });
- })
- // Executions to its end for all Jobs
- .finally(() => {
- const endTime = new Date();
- Logger.profiling(`End time: ${endTime.toISOString()};`, `Duration: ${(endTime - startTime) / 1000}s`);
- })
- );
+ return true;
+ });
+ })
+ // Executions to its end for all Jobs
+ .finally(() => {
+ const endTime = new Date();
+ Logger.profiling(
+ `End time: ${endTime.toISOString()};`,
+ `Duration: ${(endTime - startTime) / 1000}s`,
+ );
+ })
+ );
};
/**
@@ -432,39 +543,39 @@ const deleteJobsFixtures = (taskConfig, config) => {
* @returns {Promise}
*/
const deleteJobs = (jobFixtures, config) => {
- return Promise.all(
- jobFixtures.map((injectedJobFixture) => {
- const jobFixture = applyGlobalEnvSettings(injectedJobFixture);
- const jobName = jobFixture.job_name;
+ return Promise.all(
+ jobFixtures.map((injectedJobFixture) => {
+ const jobFixture = applyGlobalEnvSettings(injectedJobFixture);
+ const jobName = jobFixture.job_name;
- Logger.info(`Trying to delete Data job "${jobName}"`);
+ Logger.info(`Trying to delete Data job "${jobName}"`);
- return _getDataJob(jobFixture, config).then((outerResponse) => {
- if (outerResponse.status === 200) {
- return _deleteDataJob(jobFixture, config).then((innerResponse) => {
- if (innerResponse.status === 200) {
- Logger.info(`Data job "${jobName}" deleted`);
+ return _getDataJob(jobFixture, config).then((outerResponse) => {
+ if (outerResponse.status === 200) {
+ return _deleteDataJob(jobFixture, config).then((innerResponse) => {
+ if (innerResponse.status === 200) {
+ Logger.info(`Data job "${jobName}" deleted`);
- return true;
- }
+ return true;
+ }
- Logger.error(`Data job "${jobName}" delete failed`);
+ Logger.error(`Data job "${jobName}" delete failed`);
- return false;
- });
- }
+ return false;
+ });
+ }
- if (outerResponse.status === 404) {
- Logger.info(`Data job "${jobName}" doesn't exist`);
- } else {
- Logger.info(`Data job "${jobName}" failed to get job details`);
- Logger.error(`Data job "${jobName}" delete failed`);
- }
+ if (outerResponse.status === 404) {
+ Logger.info(`Data job "${jobName}" doesn't exist`);
+ } else {
+ Logger.info(`Data job "${jobName}" failed to get job details`);
+ Logger.error(`Data job "${jobName}" delete failed`);
+ }
- return false;
- });
- })
- ).then((responses) => responses.map((value) => !!value));
+ return false;
+ });
+ }),
+ ).then((responses) => responses.map((value) => !!value));
};
/**
@@ -475,55 +586,74 @@ const deleteJobs = (jobFixtures, config) => {
* @param {Cypress.ResolvedConfigOptions} config
* @returns {Promise<{code: number}>}
*/
-const waitForDataJobExecutionToComplete = (injectedJobFixture, jobExecutionTimeout, config) => {
- const jobFixture = applyGlobalEnvSettings(injectedJobFixture);
- const jobName = jobFixture.job_name;
- const pollInterval = 10000; // retry every 10s
-
- return _getDataJobExecutions(jobFixture, config).then((response) => {
- if (response.status !== 200) {
- Logger.error(`Failed Data job "${jobName}" executions polling`);
-
- return {
- code: 0
- };
- }
+const waitForDataJobExecutionToComplete = (
+ injectedJobFixture,
+ jobExecutionTimeout,
+ config,
+) => {
+ const jobFixture = applyGlobalEnvSettings(injectedJobFixture);
+ const jobName = jobFixture.job_name;
+ const pollInterval = 10000; // retry every 10s
+
+ return _getDataJobExecutions(jobFixture, config).then((response) => {
+ if (response.status !== 200) {
+ Logger.error(`Failed Data job "${jobName}" executions polling`);
+
+ return {
+ code: 0,
+ };
+ }
- const jobExecutions = response.data.sort(compareDatesASC);
+ const jobExecutions = response.data.sort(compareDatesASC);
- if (jobExecutions.length === 0) {
- Logger.info(`There is no Data job "${jobName}" execution to wait`);
+ if (jobExecutions.length === 0) {
+ Logger.info(`There is no Data job "${jobName}" execution to wait`);
- return {
- code: 0
- };
- }
+ return {
+ code: 0,
+ };
+ }
- const lastExecution = jobExecutions[jobExecutions.length - 1];
- const lastExecutionStatus = lastExecution.status.toLowerCase();
+ const lastExecution = jobExecutions[jobExecutions.length - 1];
+ const lastExecutionStatus = lastExecution.status.toLowerCase();
- if (lastExecutionStatus !== 'running' && lastExecutionStatus !== 'submitted') {
- Logger.info(`Data job "${jobName}" executed successfully, polling completed`);
+ if (
+ lastExecutionStatus !== "running" &&
+ lastExecutionStatus !== "submitted"
+ ) {
+ Logger.info(
+ `Data job "${jobName}" executed successfully, polling completed`,
+ );
- return {
- code: 0
- };
- }
+ return {
+ code: 0,
+ };
+ }
- if (jobExecutionTimeout <= 0) {
- Logger.error(`Data job "${jobName}" waiting time for execution exceeded, skipping and continue with next steps`);
+ if (jobExecutionTimeout <= 0) {
+ Logger.error(
+ `Data job "${jobName}" waiting time for execution exceeded, skipping and continue with next steps`,
+ );
- return {
- code: 1
- };
- }
+ return {
+ code: 1,
+ };
+ }
- Logger.info(`Data job "${jobName}", still executing... retry after ${pollInterval / 1000} seconds`);
+ Logger.info(
+ `Data job "${jobName}", still executing... retry after ${pollInterval / 1000} seconds`,
+ );
- return new Promise((resolve) => {
- setTimeout(() => resolve(), pollInterval);
- }).then(() => waitForDataJobExecutionToComplete(jobFixture, jobExecutionTimeout - pollInterval, config));
- });
+ return new Promise((resolve) => {
+ setTimeout(() => resolve(), pollInterval);
+ }).then(() =>
+ waitForDataJobExecutionToComplete(
+ jobFixture,
+ jobExecutionTimeout - pollInterval,
+ config,
+ ),
+ );
+ });
};
/**
@@ -533,26 +663,35 @@ const waitForDataJobExecutionToComplete = (injectedJobFixture, jobExecutionTimeo
* @return {Promise}
*/
const deleteDataJobsWithoutDeployment = (config) => {
- const url = `${config.env['data_jobs_url']}/data-jobs/for-team/cy-e2e-vdk/jobs?operationName=jobsQuery&variables=%7B%22pageNumber%22:1,%22pageSize%22:100,%22filter%22:%5B%5D,%22search%22:%22%22%7D&query=query%20jobsQuery($filter:%20%5BPredicate%5D,%20$search:%20String,%20$pageNumber:%20Int,%20$pageSize:%20Int)%20%7B%0A%20%20jobs(%0A%20%20%20%20pageNumber:%20$pageNumber%0A%20%20%20%20pageSize:%20$pageSize%0A%20%20%20%20filter:%20$filter%0A%20%20%20%20search:%20$search%0A%20%20)%20%7B%0A%20%20%20%20content%20%7B%0A%20%20%20%20%20%20jobName%0A%20%20%20%20%20%20config%20%7B%0A%20%20%20%20%20%20%20%20team%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20deployments%20%7B%0A%20%20%20%20%20%20%20%20id%0A%20%20%20%20%20%20%20%20enabled%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%20%20totalPages%0A%20%20%20%20totalItems%0A%20%20%7D%0A%7D`;
-
- return httpGetReq(url).then((response) => {
- const jobs = response.data.data.content;
- const remappedJobs = jobs
- .filter((job) => !job.deployments && job.jobName?.includes('cy-e2e-vdk'))
- .map((job) => {
- return {
- job_name: job.jobName,
- team: job.config?.team ?? 'cy-e2e-vdk'
- };
- });
-
- // log which Data Jobs should be deleted
- remappedJobs.forEach((job, index) => {
- Logger.debug('Deleting', index + 1, 'jobName:', job.jobName, 'team:', job?.config?.team, 'deployments:', job.deployments);
- });
+ const url = `${config.env["data_jobs_url"]}/data-jobs/for-team/cy-e2e-vdk/jobs?operationName=jobsQuery&variables=%7B%22pageNumber%22:1,%22pageSize%22:100,%22filter%22:%5B%5D,%22search%22:%22%22%7D&query=query%20jobsQuery($filter:%20%5BPredicate%5D,%20$search:%20String,%20$pageNumber:%20Int,%20$pageSize:%20Int)%20%7B%0A%20%20jobs(%0A%20%20%20%20pageNumber:%20$pageNumber%0A%20%20%20%20pageSize:%20$pageSize%0A%20%20%20%20filter:%20$filter%0A%20%20%20%20search:%20$search%0A%20%20)%20%7B%0A%20%20%20%20content%20%7B%0A%20%20%20%20%20%20jobName%0A%20%20%20%20%20%20config%20%7B%0A%20%20%20%20%20%20%20%20team%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20deployments%20%7B%0A%20%20%20%20%20%20%20%20id%0A%20%20%20%20%20%20%20%20enabled%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%20%20totalPages%0A%20%20%20%20totalItems%0A%20%20%7D%0A%7D`;
- return _deleteDataJobsWithoutDeployment(remappedJobs, config);
+ return httpGetReq(url).then((response) => {
+ const jobs = response.data.data.content;
+ const remappedJobs = jobs
+ .filter((job) => !job.deployments && job.jobName?.includes("cy-e2e-vdk"))
+ .map((job) => {
+ return {
+ job_name: job.jobName,
+ team: job.config?.team ?? "cy-e2e-vdk",
+ };
+ });
+
+ // log which Data Jobs should be deleted
+ remappedJobs.forEach((job, index) => {
+ Logger.debug(
+ "Deleting",
+ index + 1,
+ "jobName:",
+ job.jobName,
+ "team:",
+ job?.config?.team,
+ "deployments:",
+ job.deployments,
+ );
});
+
+ return _deleteDataJobsWithoutDeployment(remappedJobs, config);
+ });
};
/**
@@ -564,10 +703,10 @@ const deleteDataJobsWithoutDeployment = (config) => {
* @private
*/
const compareDatesASC = (left, right) => {
- const leftStartTime = left.start_time ? left.start_time : 0;
- const rightStartTime = right.start_time ? right.start_time : 0;
+ 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();
};
/**
@@ -582,32 +721,58 @@ const compareDatesASC = (left, right) => {
* @returns {Promise<{code: number}>}
* @private
*/
-const _triggerExecutionForJob = (jobFixture, jobExecutionTimeout, lastDeployment, neededExecutions, config, counterOfExecutions = 0) => {
- const jobName = jobFixture.job_name;
-
- if (counterOfExecutions === 0) {
- Logger.info(`Submitting ${neededExecutions} serial executions for Data job "${jobName}"`);
- } else {
- Logger.info(`Submitted ${counterOfExecutions} executions for Data job "${jobName}" and left ${neededExecutions - counterOfExecutions}`);
- }
+const _triggerExecutionForJob = (
+ jobFixture,
+ jobExecutionTimeout,
+ lastDeployment,
+ neededExecutions,
+ config,
+ counterOfExecutions = 0,
+) => {
+ const jobName = jobFixture.job_name;
+
+ if (counterOfExecutions === 0) {
+ Logger.info(
+ `Submitting ${neededExecutions} serial executions for Data job "${jobName}"`,
+ );
+ } else {
+ Logger.info(
+ `Submitted ${counterOfExecutions} executions for Data job "${jobName}" and left ${neededExecutions - counterOfExecutions}`,
+ );
+ }
- if (neededExecutions === counterOfExecutions) {
- return Promise.resolve({ code: 0 });
- }
+ if (neededExecutions === counterOfExecutions) {
+ return Promise.resolve({ code: 0 });
+ }
- // Trigger job execution
- return _executeJob(jobFixture, lastDeployment.id, config)
- .then((result) => {
- if (result.code === 0) {
- return new Promise((resolve) => {
- setTimeout(() => resolve({ code: 0 }), 5000);
- });
- }
-
- return result;
- })
- .then(() => waitForDataJobExecutionToComplete(jobFixture, jobExecutionTimeout, config))
- .then(() => _triggerExecutionForJob(jobFixture, jobExecutionTimeout, lastDeployment, neededExecutions, config, counterOfExecutions + 1));
+ // Trigger job execution
+ return _executeJob(jobFixture, lastDeployment.id, config)
+ .then((result) => {
+ if (result.code === 0) {
+ return new Promise((resolve) => {
+ setTimeout(() => resolve({ code: 0 }), 5000);
+ });
+ }
+
+ return result;
+ })
+ .then(() =>
+ waitForDataJobExecutionToComplete(
+ jobFixture,
+ jobExecutionTimeout,
+ config,
+ ),
+ )
+ .then(() =>
+ _triggerExecutionForJob(
+ jobFixture,
+ jobExecutionTimeout,
+ lastDeployment,
+ neededExecutions,
+ config,
+ counterOfExecutions + 1,
+ ),
+ );
};
/**
@@ -620,21 +785,21 @@ const _triggerExecutionForJob = (jobFixture, jobExecutionTimeout, lastDeployment
* @private
*/
const _executeJob = (jobFixture, deploymentId, config) => {
- const jobName = jobFixture.job_name;
- const teamName = jobFixture.team;
- const url = `${config.env['data_jobs_url']}/data-jobs/for-team/${teamName}/jobs/${jobName}/deployments/${deploymentId}/executions`;
+ const jobName = jobFixture.job_name;
+ const teamName = jobFixture.team;
+ const url = `${config.env["data_jobs_url"]}/data-jobs/for-team/${teamName}/jobs/${jobName}/deployments/${deploymentId}/executions`;
- Logger.info(`Submitting Data job execution for "${jobName}"`);
+ Logger.info(`Submitting Data job execution for "${jobName}"`);
- return httpPostReq(url, {}).then((response) => {
- if (response.status >= 400) {
- Logger.error(`Failed to execute Data job "${jobName}"`);
- }
+ return httpPostReq(url, {}).then((response) => {
+ if (response.status >= 400) {
+ Logger.error(`Failed to execute Data job "${jobName}"`);
+ }
- return {
- code: 0
- };
- });
+ return {
+ code: 0,
+ };
+ });
};
/**
@@ -646,17 +811,17 @@ const _executeJob = (jobFixture, deploymentId, config) => {
* @private
*/
const _getDataJobExecutionsArray = (jobFixture, config) => {
- const jobName = jobFixture.job_name;
+ const jobName = jobFixture.job_name;
- return _getDataJobExecutions(jobFixture, config).then((response) => {
- if (response.status !== 200) {
- Logger.error(`Failed to get Data job "${jobName}" executions`);
+ return _getDataJobExecutions(jobFixture, config).then((response) => {
+ if (response.status !== 200) {
+ Logger.error(`Failed to get Data job "${jobName}" executions`);
- return [];
- }
+ return [];
+ }
- return response.data && response.data.length ? response.data : [];
- });
+ return response.data && response.data.length ? response.data : [];
+ });
};
/**
@@ -668,17 +833,19 @@ const _getDataJobExecutionsArray = (jobFixture, config) => {
* @private
*/
const _getJobLastDeployment = (jobFixture, config) => {
- const jobName = jobFixture.job_name;
+ const jobName = jobFixture.job_name;
- return _getDataJobDeployments(jobFixture, config).then((response) => {
- if (response.status !== 200) {
- Logger.error(`Failed to get Data job "${jobName}" deployments`);
+ return _getDataJobDeployments(jobFixture, config).then((response) => {
+ if (response.status !== 200) {
+ Logger.error(`Failed to get Data job "${jobName}" deployments`);
- return null;
- }
+ return null;
+ }
- return response.data && response.data.length ? response.data[response.data.length - 1] : null;
- });
+ return response.data && response.data.length
+ ? response.data[response.data.length - 1]
+ : null;
+ });
};
/**
@@ -691,54 +858,72 @@ const _getJobLastDeployment = (jobFixture, config) => {
* @private
*/
const _deployDataJob = (jobFixture, jobZipFile, config) => {
- const jobName = jobFixture.job_name;
- const teamName = jobFixture.team;
- const waitForJobDeploymentTimeout = 420000; // Wait up to 7 min for deployment to complete.
-
- Logger.info(`Deploying Data job "${jobName}"`);
-
- // Upload Data Job resources
- return _sendDataJobResources(teamName, jobName, jobZipFile, config).then((response1) => {
- if (response1.status > 400) {
- Logger.error(`Failed to send Data job "${jobName}" resources to server`);
+ const jobName = jobFixture.job_name;
+ const teamName = jobFixture.team;
+ const waitForJobDeploymentTimeout = 420000; // Wait up to 7 min for deployment to complete.
- return {
- code: 1
- };
- }
-
- /**
- * @type {{version_sha: string}}
- */
- let jsonResponse;
+ Logger.info(`Deploying Data job "${jobName}"`);
- try {
- jsonResponse = response1.data;
- } catch (error) {
- Logger.error(`Cannot parse response and read SHA for deployed Data jobs resources, response =>`, response1);
+ // Upload Data Job resources
+ return _sendDataJobResources(teamName, jobName, jobZipFile, config).then(
+ (response1) => {
+ if (response1.status > 400) {
+ Logger.error(
+ `Failed to send Data job "${jobName}" resources to server`,
+ );
- throw error;
- }
+ return {
+ code: 1,
+ };
+ }
- // Deploy data job
- return new Promise((resolve) => {
- setTimeout(() => resolve(), 1000);
- })
- .then(() => _deployDataJobSHAVersion(teamName, jobName, jsonResponse.version_sha, config))
- .then((response2) => {
- if (response2.status === 202) {
- Logger.info(`Data job "${jobName}" deployment in progress...`);
-
- return _waitForDataJobDeploymentToComplete(jobFixture, waitForJobDeploymentTimeout, config);
- }
+ /**
+ * @type {{version_sha: string}}
+ */
+ let jsonResponse;
- Logger.error(`Data job "${jobName}" deployment failed`);
+ try {
+ jsonResponse = response1.data;
+ } catch (error) {
+ Logger.error(
+ `Cannot parse response and read SHA for deployed Data jobs resources, response =>`,
+ response1,
+ );
- return {
- code: 0
- };
- });
- });
+ throw error;
+ }
+
+ // Deploy data job
+ return new Promise((resolve) => {
+ setTimeout(() => resolve(), 1000);
+ })
+ .then(() =>
+ _deployDataJobSHAVersion(
+ teamName,
+ jobName,
+ jsonResponse.version_sha,
+ config,
+ ),
+ )
+ .then((response2) => {
+ if (response2.status === 202) {
+ Logger.info(`Data job "${jobName}" deployment in progress...`);
+
+ return _waitForDataJobDeploymentToComplete(
+ jobFixture,
+ waitForJobDeploymentTimeout,
+ config,
+ );
+ }
+
+ Logger.error(`Data job "${jobName}" deployment failed`);
+
+ return {
+ code: 0,
+ };
+ });
+ },
+ );
};
/**
@@ -751,32 +936,42 @@ const _deployDataJob = (jobFixture, jobZipFile, config) => {
* @private
*/
const _waitForDataJobDeploymentToComplete = (jobFixture, timeout, config) => {
- const jobName = jobFixture.job_name;
- const waitInterval = 10000; // retry every 10s
+ const jobName = jobFixture.job_name;
+ const waitInterval = 10000; // retry every 10s
- return _getDataJobDeployments(jobFixture, config).then((resp) => {
- if (resp.status === 200 && resp.data.length > 0) {
- Logger.info(`Data job "${jobName}" deployment finished`);
+ return _getDataJobDeployments(jobFixture, config).then((resp) => {
+ if (resp.status === 200 && resp.data.length > 0) {
+ Logger.info(`Data job "${jobName}" deployment finished`);
- return {
- code: 0
- };
- }
+ return {
+ code: 0,
+ };
+ }
- if (timeout <= 0) {
- Logger.error(`Data job "${jobName}" waiting time to deploy exceeded, skipping and continue with next steps`);
+ if (timeout <= 0) {
+ Logger.error(
+ `Data job "${jobName}" waiting time to deploy exceeded, skipping and continue with next steps`,
+ );
- return {
- code: 0
- };
- }
+ return {
+ code: 0,
+ };
+ }
- Logger.info(`Data job "${jobName}", still deploying... retry after ${waitInterval / 1000} seconds`);
+ Logger.info(
+ `Data job "${jobName}", still deploying... retry after ${waitInterval / 1000} seconds`,
+ );
- return new Promise((resolve) => {
- setTimeout(() => resolve(), waitInterval);
- }).then(() => _waitForDataJobDeploymentToComplete(jobFixture, timeout - waitInterval, config));
- });
+ return new Promise((resolve) => {
+ setTimeout(() => resolve(), waitInterval);
+ }).then(() =>
+ _waitForDataJobDeploymentToComplete(
+ jobFixture,
+ timeout - waitInterval,
+ config,
+ ),
+ );
+ });
};
/**
@@ -788,13 +983,13 @@ const _waitForDataJobDeploymentToComplete = (jobFixture, timeout, config) => {
* @private
*/
const _createDataJob = (jobFixture, config) => {
- const teamName = jobFixture.team;
- const jobName = jobFixture.job_name;
- const url = `${config.env['data_jobs_url']}/data-jobs/for-team/${teamName}/jobs`;
+ const teamName = jobFixture.team;
+ const jobName = jobFixture.job_name;
+ const url = `${config.env["data_jobs_url"]}/data-jobs/for-team/${teamName}/jobs`;
- Logger.debug(`Creating Data job "${jobName}" for Team "${teamName}"`);
+ Logger.debug(`Creating Data job "${jobName}" for Team "${teamName}"`);
- return httpPostReq(url, jobFixture);
+ return httpPostReq(url, jobFixture);
};
/**
@@ -808,12 +1003,18 @@ const _createDataJob = (jobFixture, config) => {
* @returns {Promise>>}
* @private
*/
-const _updateDataJob = (teamName, jobName, deploymentHash, jobFixture, config) => {
- const url = `${config.env['data_jobs_url']}/data-jobs/for-team/${teamName}/jobs/${jobName}/deployments/${deploymentHash}`;
-
- Logger.debug(`Updating Data job "${jobName}" for Team "${teamName}"`);
-
- return httpPatchReq(url, jobFixture);
+const _updateDataJob = (
+ teamName,
+ jobName,
+ deploymentHash,
+ jobFixture,
+ config,
+) => {
+ const url = `${config.env["data_jobs_url"]}/data-jobs/for-team/${teamName}/jobs/${jobName}/deployments/${deploymentHash}`;
+
+ Logger.debug(`Updating Data job "${jobName}" for Team "${teamName}"`);
+
+ return httpPatchReq(url, jobFixture);
};
/**
@@ -825,13 +1026,13 @@ const _updateDataJob = (teamName, jobName, deploymentHash, jobFixture, config) =
* @private
*/
const _getDataJob = (jobFixture, config) => {
- const teamName = jobFixture.team;
- const jobName = jobFixture.job_name;
- const url = `${config.env['data_jobs_url']}/data-jobs/for-team/${teamName}/jobs/${jobName}`;
+ const teamName = jobFixture.team;
+ const jobName = jobFixture.job_name;
+ const url = `${config.env["data_jobs_url"]}/data-jobs/for-team/${teamName}/jobs/${jobName}`;
- Logger.debug(`Get Data job "${jobName}"`);
+ Logger.debug(`Get Data job "${jobName}"`);
- return httpGetReq(url);
+ return httpGetReq(url);
};
/**
@@ -843,13 +1044,13 @@ const _getDataJob = (jobFixture, config) => {
* @private
*/
const _deleteDataJob = (jobFixture, config) => {
- const teamName = jobFixture.team;
- const jobName = jobFixture.job_name;
- const url = `${config.env['data_jobs_url']}/data-jobs/for-team/${teamName}/jobs/${jobName}`;
+ const teamName = jobFixture.team;
+ const jobName = jobFixture.job_name;
+ const url = `${config.env["data_jobs_url"]}/data-jobs/for-team/${teamName}/jobs/${jobName}`;
- Logger.debug(`Delete Data job "${jobName}"`);
+ Logger.debug(`Delete Data job "${jobName}"`);
- return httpDeleteReq(url);
+ return httpDeleteReq(url);
};
/**
@@ -861,13 +1062,13 @@ const _deleteDataJob = (jobFixture, config) => {
* @private
*/
const _getDataJobExecutions = (jobFixture, config) => {
- const jobName = jobFixture.job_name;
- const teamName = jobFixture.team;
- const url = `${config.env['data_jobs_url']}/data-jobs/for-team/${teamName}/jobs/${jobName}/executions`;
+ const jobName = jobFixture.job_name;
+ const teamName = jobFixture.team;
+ const url = `${config.env["data_jobs_url"]}/data-jobs/for-team/${teamName}/jobs/${jobName}/executions`;
- Logger.debug(`Get Data job "${jobName}" executions`);
+ Logger.debug(`Get Data job "${jobName}" executions`);
- return httpGetReq(url);
+ return httpGetReq(url);
};
/**
@@ -879,13 +1080,13 @@ const _getDataJobExecutions = (jobFixture, config) => {
* @private
*/
const _getDataJobDeployments = (jobFixture, config) => {
- const jobName = jobFixture.job_name;
- const teamName = jobFixture.team;
- const url = `${config.env['data_jobs_url']}/data-jobs/for-team/${teamName}/jobs/${jobName}/deployments`;
+ const jobName = jobFixture.job_name;
+ const teamName = jobFixture.team;
+ const url = `${config.env["data_jobs_url"]}/data-jobs/for-team/${teamName}/jobs/${jobName}/deployments`;
- Logger.debug(`Get Data job "${jobName}" deployments`);
+ Logger.debug(`Get Data job "${jobName}" deployments`);
- return httpGetReq(url);
+ return httpGetReq(url);
};
/**
@@ -899,20 +1100,23 @@ const _getDataJobDeployments = (jobFixture, config) => {
* @private
*/
const _sendDataJobResources = (teamName, jobName, jobZipFile, config) => {
- const url = `${config.env['data_jobs_url']}/data-jobs/for-team/${teamName}/jobs/${jobName}/sources`;
- let buffer;
-
- try {
- buffer = Buffer.from(jobZipFile, 'base64');
- } catch (error) {
- Logger.error(`Cannot convert from base64 to Buffer Data job "${jobName}" zip file`, error);
+ const url = `${config.env["data_jobs_url"]}/data-jobs/for-team/${teamName}/jobs/${jobName}/sources`;
+ let buffer;
+
+ try {
+ buffer = Buffer.from(jobZipFile, "base64");
+ } catch (error) {
+ Logger.error(
+ `Cannot convert from base64 to Buffer Data job "${jobName}" zip file`,
+ error,
+ );
- throw error;
- }
+ throw error;
+ }
- Logger.debug(`Sending Data job resources to API, buffer =>`, buffer);
+ Logger.debug(`Sending Data job resources to API, buffer =>`, buffer);
- return httpPostReq(url, buffer, { 'Content-Type': '' });
+ return httpPostReq(url, buffer, { "Content-Type": "" });
};
/**
@@ -926,15 +1130,15 @@ const _sendDataJobResources = (teamName, jobName, jobZipFile, config) => {
* @private
*/
const _deployDataJobSHAVersion = (teamName, jobName, shaVersion, config) => {
- const url = `${config.env['data_jobs_url']}/data-jobs/for-team/${teamName}/jobs/${jobName}/deployments`;
+ const url = `${config.env["data_jobs_url"]}/data-jobs/for-team/${teamName}/jobs/${jobName}/deployments`;
- Logger.debug(`Deploying Data job SHA version =>`, shaVersion);
+ Logger.debug(`Deploying Data job SHA version =>`, shaVersion);
- return httpPostReq(url, {
- job_version: shaVersion,
- mode: 'release',
- enabled: true
- });
+ return httpPostReq(url, {
+ job_version: shaVersion,
+ mode: "release",
+ enabled: true,
+ });
};
/**
@@ -945,45 +1149,53 @@ const _deployDataJobSHAVersion = (teamName, jobName, shaVersion, config) => {
* @private
*/
const _loadFixturesValuesAndBinariesPaths = (pathToFixtures) => {
- return Promise.resolve(
- pathToFixtures.map((relativePathToFixture) => {
- return {
- pathToFixture: path.join(__dirname, `../../fixtures/${relativePathToFixture.pathToFixture.replace(/^\//, '')}`),
- pathToZipFile: relativePathToFixture.pathToZipFile ? path.join(__dirname, `../../fixtures/${relativePathToFixture.pathToZipFile.replace(/^\//, '')}`) : null
- };
- })
- ).then((pathToFixturesAndBinaries) => {
- // Resolving files and parsing to JSON and passing down the stream
- return pathToFixturesAndBinaries.map((data) => {
- const pathToFixture = data.pathToFixture;
-
- Logger.debug(`Loading Data job fixture located on =>`, pathToFixture);
-
- let jobFile;
- let jobFixture;
-
- try {
- jobFile = fs.readFileSync(pathToFixture, { encoding: 'utf8' });
- } catch (error) {
- Logger.error(`Cannot read file located on =>`, pathToFixture);
-
- throw error;
- }
+ return Promise.resolve(
+ pathToFixtures.map((relativePathToFixture) => {
+ return {
+ pathToFixture: path.join(
+ __dirname,
+ `../../fixtures/${relativePathToFixture.pathToFixture.replace(/^\//, "")}`,
+ ),
+ pathToZipFile: relativePathToFixture.pathToZipFile
+ ? path.join(
+ __dirname,
+ `../../fixtures/${relativePathToFixture.pathToZipFile.replace(/^\//, "")}`,
+ )
+ : null,
+ };
+ }),
+ ).then((pathToFixturesAndBinaries) => {
+ // Resolving files and parsing to JSON and passing down the stream
+ return pathToFixturesAndBinaries.map((data) => {
+ const pathToFixture = data.pathToFixture;
+
+ Logger.debug(`Loading Data job fixture located on =>`, pathToFixture);
+
+ let jobFile;
+ let jobFixture;
+
+ try {
+ jobFile = fs.readFileSync(pathToFixture, { encoding: "utf8" });
+ } catch (error) {
+ Logger.error(`Cannot read file located on =>`, pathToFixture);
- try {
- jobFixture = applyGlobalEnvSettings(JSON.parse(jobFile));
+ throw error;
+ }
- return {
- jobFixture,
- pathToZipFile: data.pathToZipFile
- };
- } catch (error) {
- Logger.error(`Cannot parse read file located on =>`, pathToFixture);
+ try {
+ jobFixture = applyGlobalEnvSettings(JSON.parse(jobFile));
- throw error;
- }
- });
+ return {
+ jobFixture,
+ pathToZipFile: data.pathToZipFile,
+ };
+ } catch (error) {
+ Logger.error(`Cannot parse read file located on =>`, pathToFixture);
+
+ throw error;
+ }
});
+ });
};
/**
@@ -995,27 +1207,32 @@ const _loadFixturesValuesAndBinariesPaths = (pathToFixtures) => {
* @return {Promise}
* @private
*/
-const _deleteDataJobsWithoutDeployment = (jobFixtures, config, responses = []) => {
- const chunk = jobFixtures.length > 10 ? jobFixtures.splice(0, 10) : jobFixtures;
-
- return deleteJobs(chunk, config).then((statuses) => {
- responses.push(...statuses);
-
- if (jobFixtures.length > 0) {
- return _deleteDataJobsWithoutDeployment(jobFixtures, config, responses);
- }
+const _deleteDataJobsWithoutDeployment = (
+ jobFixtures,
+ config,
+ responses = [],
+) => {
+ const chunk =
+ jobFixtures.length > 10 ? jobFixtures.splice(0, 10) : jobFixtures;
+
+ return deleteJobs(chunk, config).then((statuses) => {
+ responses.push(...statuses);
+
+ if (jobFixtures.length > 0) {
+ return _deleteDataJobsWithoutDeployment(jobFixtures, config, responses);
+ }
- return responses;
- });
+ return responses;
+ });
};
module.exports = {
- createDeployJobs,
- deleteJobsFixtures,
- deleteJobs,
- provideDataJobsExecutions,
- changeJobsStatusesFixtures,
- waitForDataJobExecutionToComplete,
- deleteDataJobsWithoutDeployment,
- compareDatesASC
+ createDeployJobs,
+ deleteJobsFixtures,
+ deleteJobs,
+ provideDataJobsExecutions,
+ changeJobsStatusesFixtures,
+ waitForDataJobExecutionToComplete,
+ deleteDataJobsWithoutDeployment,
+ compareDatesASC,
};
diff --git a/projects/frontend/data-pipelines/gui/e2e/plugins/helpers/logger-helpers.plugins.js b/projects/frontend/data-pipelines/gui/e2e/plugins/helpers/logger-helpers.plugins.js
index 698d4acac8..23fa2dcc15 100644
--- a/projects/frontend/data-pipelines/gui/e2e/plugins/helpers/logger-helpers.plugins.js
+++ b/projects/frontend/data-pipelines/gui/e2e/plugins/helpers/logger-helpers.plugins.js
@@ -9,7 +9,7 @@
* @param args
*/
const consoleLog = (...args) => {
- console.log('LOG --------->', ...args);
+ console.log("LOG --------->", ...args);
};
/**
@@ -18,7 +18,7 @@ const consoleLog = (...args) => {
* @param args
*/
const consoleInfo = (...args) => {
- console.log('INFO -------->', ...args);
+ console.log("INFO -------->", ...args);
};
/**
@@ -27,7 +27,7 @@ const consoleInfo = (...args) => {
* @param args
*/
const consoleDebug = (...args) => {
- console.log('DEBUG ------->', ...args);
+ console.log("DEBUG ------->", ...args);
};
/**
@@ -36,7 +36,7 @@ const consoleDebug = (...args) => {
* @param args
*/
const consoleError = (...args) => {
- console.log('ERROR ------->', ...args);
+ console.log("ERROR ------->", ...args);
};
/**
@@ -45,15 +45,15 @@ const consoleError = (...args) => {
* @param args
*/
const consoleProfiling = (...args) => {
- console.log('PROFILING ------->', ...args);
+ console.log("PROFILING ------->", ...args);
};
module.exports = {
- Logger: {
- log: consoleLog,
- info: consoleInfo,
- debug: consoleDebug,
- error: consoleError,
- profiling: consoleProfiling
- }
+ Logger: {
+ log: consoleLog,
+ info: consoleInfo,
+ debug: consoleDebug,
+ error: consoleError,
+ profiling: consoleProfiling,
+ },
};
diff --git a/projects/frontend/data-pipelines/gui/e2e/plugins/helpers/util-helpers.plugins.js b/projects/frontend/data-pipelines/gui/e2e/plugins/helpers/util-helpers.plugins.js
index 4c4ab08d48..8ca5b1dd45 100644
--- a/projects/frontend/data-pipelines/gui/e2e/plugins/helpers/util-helpers.plugins.js
+++ b/projects/frontend/data-pipelines/gui/e2e/plugins/helpers/util-helpers.plugins.js
@@ -3,13 +3,13 @@
* SPDX-License-Identifier: Apache-2.0
*/
-const { v4 } = require('uuid');
+const { v4 } = require("uuid");
-const { Logger } = require('./logger-helpers.plugins');
+const { Logger } = require("./logger-helpers.plugins");
const JWT_TOKEN_REGEX = new RegExp(`([^\.]+)\.([^\.]+)\.([^\.]*)`);
-const DEFAULT_TEST_ENV_VAR = 'lib';
+const DEFAULT_TEST_ENV_VAR = "lib";
/**
* ** Generate UUID.
@@ -18,15 +18,15 @@ const DEFAULT_TEST_ENV_VAR = 'lib';
* @returns {Cypress.Chainable<{uuid: string}>|{uuid: string}}
*/
const generateUUID = (asynchronous = false) => {
- const uuid = v4();
+ const uuid = v4();
- Logger.info(`Generated uuid ${uuid}`);
+ Logger.info(`Generated uuid ${uuid}`);
- if (asynchronous) {
- return Promise.resolve({ uuid });
- }
+ if (asynchronous) {
+ return Promise.resolve({ uuid });
+ }
- return { uuid };
+ return { uuid };
};
/**
@@ -37,23 +37,23 @@ const generateUUID = (asynchronous = false) => {
* @returns {{header:string; claims:{[key: string]: any;}; signature:string;}} The decoded token.
*/
const parseJWTToken = (token) => {
- const parts = (token && token.match(JWT_TOKEN_REGEX)) || null;
- if (!parts) {
- throw new Error('Invalid JWT Format');
- }
-
- const rawHeader = parts[1];
- const rawBody = parts[2];
- const signature = parts[3];
-
- const header = JSON.parse(_toUnicodeString(rawHeader));
- const claims = JSON.parse(_toUnicodeString(rawBody));
-
- return {
- header,
- claims,
- signature
- };
+ const parts = (token && token.match(JWT_TOKEN_REGEX)) || null;
+ if (!parts) {
+ throw new Error("Invalid JWT Format");
+ }
+
+ const rawHeader = parts[1];
+ const rawBody = parts[2];
+ const signature = parts[3];
+
+ const header = JSON.parse(_toUnicodeString(rawHeader));
+ const claims = JSON.parse(_toUnicodeString(rawBody));
+
+ return {
+ header,
+ claims,
+ signature,
+ };
};
/**
@@ -64,31 +64,41 @@ const parseJWTToken = (token) => {
* @param {string} injectedTestUid
* @returns {string|object|any}
*/
-const applyGlobalEnvSettings = (loadedElement, injectedTestEnvVar = null, injectedTestUid = null) => {
- const TEST_ENV_VAR = injectedTestEnvVar ?? _loadTestEnvironmentVar();
- const TEST_UID = injectedTestUid ?? _loadTestUid();
-
- if (typeof loadedElement === 'string') {
- return loadedElement.replace('$env-placeholder$', `${TEST_ENV_VAR}-${TEST_UID}`);
- }
-
- 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}-${TEST_UID}`);
- }
+const applyGlobalEnvSettings = (
+ loadedElement,
+ injectedTestEnvVar = null,
+ injectedTestUid = null,
+) => {
+ const TEST_ENV_VAR = injectedTestEnvVar ?? _loadTestEnvironmentVar();
+ const TEST_UID = injectedTestUid ?? _loadTestUid();
+
+ if (typeof loadedElement === "string") {
+ return loadedElement.replace(
+ "$env-placeholder$",
+ `${TEST_ENV_VAR}-${TEST_UID}`,
+ );
+ }
+
+ 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}-${TEST_UID}`,
+ );
+ }
- loadedElement[key] = value;
- }
+ loadedElement[key] = value;
+ }
- if (typeof value === 'object') {
- loadedElement[key] = applyGlobalEnvSettings(value);
- }
- });
- }
+ if (typeof value === "object") {
+ loadedElement[key] = applyGlobalEnvSettings(value);
+ }
+ });
+ }
- return loadedElement;
+ return loadedElement;
};
/**
@@ -98,35 +108,42 @@ const applyGlobalEnvSettings = (loadedElement, injectedTestEnvVar = null, inject
* @param {number} numberOfArrayElements
*/
const trimArraysToNElements = (object, numberOfArrayElements) => {
- if (typeof object === 'undefined' || object === null || Number.isNaN(object)) {
- return object;
- }
-
- if (object instanceof Array) {
- if (object.length > numberOfArrayElements) {
- const chunk = object.slice(0, numberOfArrayElements);
+ if (
+ typeof object === "undefined" ||
+ object === null ||
+ Number.isNaN(object)
+ ) {
+ return object;
+ }
- return [...chunk, `... ${object.length - numberOfArrayElements} more elements in the Array ...`];
- }
+ if (object instanceof Array) {
+ if (object.length > numberOfArrayElements) {
+ const chunk = object.slice(0, numberOfArrayElements);
- return object;
+ return [
+ ...chunk,
+ `... ${object.length - numberOfArrayElements} more elements in the Array ...`,
+ ];
}
- if (typeof object === 'object') {
- Object.entries(object).forEach(([key, value]) => {
- if (object instanceof Array) {
- value = trimArraysToNElements(value, numberOfArrayElements);
+ return object;
+ }
+
+ if (typeof object === "object") {
+ Object.entries(object).forEach(([key, value]) => {
+ if (object instanceof Array) {
+ value = trimArraysToNElements(value, numberOfArrayElements);
- object[key] = value;
- }
+ object[key] = value;
+ }
- if (typeof value === 'object') {
- object[key] = trimArraysToNElements(value, numberOfArrayElements);
- }
- });
- }
+ if (typeof value === "object") {
+ object[key] = trimArraysToNElements(value, numberOfArrayElements);
+ }
+ });
+ }
- return object;
+ return object;
};
/**
@@ -139,15 +156,17 @@ const trimArraysToNElements = (object, numberOfArrayElements) => {
* @private
*/
const _toUnicodeString = (encoded) => {
- // URL-save Base64 strings do not contain padding `=` characters, so add them.
- const missingPadding = encoded.length % 4;
- if (missingPadding !== 0) {
- encoded += '='.repeat(4 - missingPadding);
- }
-
- // Additional URL-safe character replacement
- encoded = encoded.replace(/-/g, '+').replace(/_/g, '/');
- return decodeURIComponent(Array.prototype.map.call(atob(encoded), _escapeMultibyteCharacter).join(''));
+ // URL-save Base64 strings do not contain padding `=` characters, so add them.
+ const missingPadding = encoded.length % 4;
+ if (missingPadding !== 0) {
+ encoded += "=".repeat(4 - missingPadding);
+ }
+
+ // Additional URL-safe character replacement
+ encoded = encoded.replace(/-/g, "+").replace(/_/g, "/");
+ return decodeURIComponent(
+ Array.prototype.map.call(atob(encoded), _escapeMultibyteCharacter).join(""),
+ );
};
/**
@@ -158,7 +177,7 @@ const _toUnicodeString = (encoded) => {
* @private
*/
const _escapeMultibyteCharacter = (c) => {
- return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
+ return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
};
/**
@@ -167,52 +186,68 @@ const _escapeMultibyteCharacter = (c) => {
* @private
*/
const _loadTestEnvironmentVar = () => {
- /**
- * @type {string}
- */
- let testEnv;
-
- if (typeof process !== 'undefined' && process.env?.CYPRESS_test_environment) {
- testEnv = process.env.CYPRESS_test_environment;
- } else if (typeof Cypress !== 'undefined' && Cypress.env && Cypress.env('test_environment')) {
- testEnv = Cypress?.env('test_environment');
- }
-
- if (!testEnv) {
- Logger.info(`test_environment is not set in system env variable or Cypress env variable.`);
- Logger.debug(`Because test_environment is not explicitly set will use default: ${DEFAULT_TEST_ENV_VAR}`);
-
- testEnv = DEFAULT_TEST_ENV_VAR;
- }
-
- return testEnv;
+ /**
+ * @type {string}
+ */
+ let testEnv;
+
+ if (typeof process !== "undefined" && process.env?.CYPRESS_test_environment) {
+ testEnv = process.env.CYPRESS_test_environment;
+ } else if (
+ typeof Cypress !== "undefined" &&
+ Cypress.env &&
+ Cypress.env("test_environment")
+ ) {
+ testEnv = Cypress?.env("test_environment");
+ }
+
+ if (!testEnv) {
+ Logger.info(
+ `test_environment is not set in system env variable or Cypress env variable.`,
+ );
+ Logger.debug(
+ `Because test_environment is not explicitly set will use default: ${DEFAULT_TEST_ENV_VAR}`,
+ );
+
+ testEnv = DEFAULT_TEST_ENV_VAR;
+ }
+
+ return testEnv;
};
const _loadTestUid = () => {
- /**
- * @type {string}
- */
- let guid;
-
- if (typeof process !== 'undefined' && process.env?.CYPRESS_test_guid) {
- guid = process.env.CYPRESS_test_guid;
- } else if (typeof Cypress !== 'undefined' && Cypress.env && Cypress.env('test_guid')) {
- guid = Cypress.env('test_guid');
- }
-
- if (!guid) {
- guid = '1a4d2540515640d3';
-
- Logger.info(`test_guid is not set in system env variable or Cypress env variable.`);
- Logger.debug(`Because test_guid is not explicitly set will use default constant: ${guid}`);
- }
-
- return guid;
+ /**
+ * @type {string}
+ */
+ let guid;
+
+ if (typeof process !== "undefined" && process.env?.CYPRESS_test_guid) {
+ guid = process.env.CYPRESS_test_guid;
+ } else if (
+ typeof Cypress !== "undefined" &&
+ Cypress.env &&
+ Cypress.env("test_guid")
+ ) {
+ guid = Cypress.env("test_guid");
+ }
+
+ if (!guid) {
+ guid = "1a4d2540515640d3";
+
+ Logger.info(
+ `test_guid is not set in system env variable or Cypress env variable.`,
+ );
+ Logger.debug(
+ `Because test_guid is not explicitly set will use default constant: ${guid}`,
+ );
+ }
+
+ return guid;
};
module.exports = {
- generateUUID,
- applyGlobalEnvSettings,
- parseJWTToken,
- trimArraysToNElements
+ generateUUID,
+ applyGlobalEnvSettings,
+ parseJWTToken,
+ trimArraysToNElements,
};
diff --git a/projects/frontend/data-pipelines/gui/e2e/plugins/index.js b/projects/frontend/data-pipelines/gui/e2e/plugins/index.js
index 10827b4667..5d72508861 100644
--- a/projects/frontend/data-pipelines/gui/e2e/plugins/index.js
+++ b/projects/frontend/data-pipelines/gui/e2e/plugins/index.js
@@ -17,15 +17,30 @@
// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)
-const path = require('path');
+const path = require("path");
-const { install, ensureBrowserFlags } = require('@neuralegion/cypress-har-generator');
+const {
+ install,
+ ensureBrowserFlags,
+} = require("@neuralegion/cypress-har-generator");
-const { generateUUID } = require('./helpers/util-helpers.plugins');
+const { generateUUID } = require("./helpers/util-helpers.plugins");
-const { getAccessTokenAsynchronous, setAccessTokenAsynchronous, getAccessTokenSynchronous } = require('./helpers/authentication-helpers.plugins');
+const {
+ getAccessTokenAsynchronous,
+ setAccessTokenAsynchronous,
+ getAccessTokenSynchronous,
+} = require("./helpers/authentication-helpers.plugins");
-const { createDeployJobs, provideDataJobsExecutions, waitForDataJobExecutionToComplete, deleteJobs, deleteJobsFixtures, changeJobsStatusesFixtures, deleteDataJobsWithoutDeployment } = require('./helpers/job-helpers.plugins');
+const {
+ createDeployJobs,
+ provideDataJobsExecutions,
+ waitForDataJobExecutionToComplete,
+ deleteJobs,
+ deleteJobsFixtures,
+ changeJobsStatusesFixtures,
+ deleteDataJobsWithoutDeployment,
+} = require("./helpers/job-helpers.plugins");
/**
* @type {Cypress.PluginConfig}
@@ -33,148 +48,158 @@ const { createDeployJobs, provideDataJobsExecutions, waitForDataJobExecutionToCo
// eslint-disable-next-line no-unused-vars
// `cypressConfig` is the resolved Cypress config
module.exports = (on, cypressConfig) => {
- const TASKS = {
- /**
- * ** Delete Data Jobs without deployment with parallelism.
- *
- * @return {Promise}
- */
- deleteDataJobsWithoutDeployment: () => {
- return deleteDataJobsWithoutDeployment({ ...cypressConfig });
- },
- /**
- * ** Create test Data Jobs if they don't exist.
- *
- * @param {{relativePathToFixtures: Array<{pathToFixture:string; pathToZipFile:string;}>}} taskConfig - configuration for task.
- * relativePathToFixtures provides relative paths for fixtures files starting from directory fixtures
- * e.g. {
- * relativePathToFixtures: [
- * {
- * pathToFixture: '/base/data-jobs/cy-e2e-vdk/cy-e2e-vdk-failing-v0.json',
- * pathToZipFile: '/base/data-jobs/cy-e2e-vdk/cy-e2e-vdk-failing-v0.zip'
- * }
- * ]
- * }
- * @returns {Promise}
- */
- createDeployJobs: (taskConfig) => {
- return createDeployJobs(taskConfig, { ...cypressConfig });
- },
- /**
- * ** Provide Data Jobs executions.
- *
- * @param {{relativePathToFixtures: Array<{pathToFixture:string; executions?: number;}>;}} taskConfig - configuration for task.
- * relativePathToFixtures provides relative paths for fixtures files starting from directory fixtures
- * e.g. {
- * relativePathToFixtures: [
- * {
- * pathToFixture: '/base/data-jobs/cy-e2e-vdk/cy-e2e-vdk-failing-v0.json',
- * executions: 2
- * }
- * ]
- * }
- * @returns {Promise}
- */
- provideDataJobsExecutions: (taskConfig) => {
- return provideDataJobsExecutions(taskConfig, { ...cypressConfig });
- },
- /**
- * ** Wait for Data Jobs execution for complete.
- *
- * @param {{job_name:string; description:string; team:string; config:{db_default_type:string; contacts:{}; schedule:{schedule_cron:string}; generate_keytab:boolean; enable_execution_notifications:boolean}}} jobFixture
- * @param {number} jobExecutionTimeout - job execution timeout
- * @returns {Promise<{code: number}>}
- */
- waitForDataJobExecutionToComplete: ({ jobFixture, jobExecutionTimeout = 180000 }) => {
- return waitForDataJobExecutionToComplete(jobFixture, jobExecutionTimeout, { ...cypressConfig });
- },
- /**
- * ** Change Data Jobs statuses for provided fixtures.
- *
- * @param {{relativePathToFixtures: Array<{pathToFixture:string;}>; status: boolean;}} taskConfig - configuration for task.
- * relativePathToFixtures provides relative paths for fixtures files starting from directory fixtures
- * e.g. {
- * relativePathToFixtures: [
- * {
- * pathToFixture: '/base/data-jobs/cy-e2e-vdk/cy-e2e-vdk-failing-v0.json'
- * }
- * ],
- * status: boolean
- * }
- * @returns {Promise}
- */
- changeJobsStatusesFixtures: (taskConfig) => {
- return changeJobsStatusesFixtures(taskConfig, { ...cypressConfig });
- },
- /**
- * ** Delete Jobs for provided fixtures paths.
- *
- * @param {{relativePathToFixtures: Array<{pathToFixture:string;}>; optional?: boolean;}} taskConfig - configuration for task.
- * relativePathToFixtures provides relative paths for fixtures files starting from directory fixtures
- * optional if set to true will instruct the plugin to not log console error, if deletion status is different from 2xx, (e.g. 404 or 500)
- * e.g. {
- * relativePathToFixtures: [
- * {
- * pathToFixture: '/base/data-jobs/cy-e2e-vdk/cy-e2e-vdk-failing-v0.json'
- * }
- * ],
- * optional: true
- * }
- * @returns {Promise}
- */
- deleteJobsFixtures: (taskConfig) => {
- return deleteJobsFixtures(taskConfig, { ...cypressConfig });
- },
- /**
- * ** Delete Data jobs if they exist.
- *
- * @param {Array<{job_name:string; description:string; team:string; config:{db_default_type:string; contacts:{}; schedule:{schedule_cron:string}; generate_keytab:boolean; enable_execution_notifications:boolean}}>} jobFixtures
- * @param {Cypress.ResolvedConfigOptions} config
- * @returns {Promise}
- */
- deleteJobs: ({ jobFixtures }) => {
- return deleteJobs(jobFixtures, { ...cypressConfig });
- },
- /**
- * ** Get JWT access token asynchronous.
- */
- getAccessToken: getAccessTokenAsynchronous,
- /**
- * ** Set JWT access token asynchronous.
- */
- setAccessToken: setAccessTokenAsynchronous,
- /**
- * ** Generate UUID.
- *
- * @returns {Cypress.Chainable<{uuid: string}>}
- */
- generateUUID: () => {
- return generateUUID(true);
- }
- };
+ const TASKS = {
+ /**
+ * ** Delete Data Jobs without deployment with parallelism.
+ *
+ * @return {Promise}
+ */
+ deleteDataJobsWithoutDeployment: () => {
+ return deleteDataJobsWithoutDeployment({ ...cypressConfig });
+ },
+ /**
+ * ** Create test Data Jobs if they don't exist.
+ *
+ * @param {{relativePathToFixtures: Array<{pathToFixture:string; pathToZipFile:string;}>}} taskConfig - configuration for task.
+ * relativePathToFixtures provides relative paths for fixtures files starting from directory fixtures
+ * e.g. {
+ * relativePathToFixtures: [
+ * {
+ * pathToFixture: '/base/data-jobs/cy-e2e-vdk/cy-e2e-vdk-failing-v0.json',
+ * pathToZipFile: '/base/data-jobs/cy-e2e-vdk/cy-e2e-vdk-failing-v0.zip'
+ * }
+ * ]
+ * }
+ * @returns {Promise}
+ */
+ createDeployJobs: (taskConfig) => {
+ return createDeployJobs(taskConfig, { ...cypressConfig });
+ },
+ /**
+ * ** Provide Data Jobs executions.
+ *
+ * @param {{relativePathToFixtures: Array<{pathToFixture:string; executions?: number;}>;}} taskConfig - configuration for task.
+ * relativePathToFixtures provides relative paths for fixtures files starting from directory fixtures
+ * e.g. {
+ * relativePathToFixtures: [
+ * {
+ * pathToFixture: '/base/data-jobs/cy-e2e-vdk/cy-e2e-vdk-failing-v0.json',
+ * executions: 2
+ * }
+ * ]
+ * }
+ * @returns {Promise}
+ */
+ provideDataJobsExecutions: (taskConfig) => {
+ return provideDataJobsExecutions(taskConfig, { ...cypressConfig });
+ },
+ /**
+ * ** Wait for Data Jobs execution for complete.
+ *
+ * @param {{job_name:string; description:string; team:string; config:{db_default_type:string; contacts:{}; schedule:{schedule_cron:string}; generate_keytab:boolean; enable_execution_notifications:boolean}}} jobFixture
+ * @param {number} jobExecutionTimeout - job execution timeout
+ * @returns {Promise<{code: number}>}
+ */
+ waitForDataJobExecutionToComplete: ({
+ jobFixture,
+ jobExecutionTimeout = 180000,
+ }) => {
+ return waitForDataJobExecutionToComplete(
+ jobFixture,
+ jobExecutionTimeout,
+ { ...cypressConfig },
+ );
+ },
+ /**
+ * ** Change Data Jobs statuses for provided fixtures.
+ *
+ * @param {{relativePathToFixtures: Array<{pathToFixture:string;}>; status: boolean;}} taskConfig - configuration for task.
+ * relativePathToFixtures provides relative paths for fixtures files starting from directory fixtures
+ * e.g. {
+ * relativePathToFixtures: [
+ * {
+ * pathToFixture: '/base/data-jobs/cy-e2e-vdk/cy-e2e-vdk-failing-v0.json'
+ * }
+ * ],
+ * status: boolean
+ * }
+ * @returns {Promise}
+ */
+ changeJobsStatusesFixtures: (taskConfig) => {
+ return changeJobsStatusesFixtures(taskConfig, { ...cypressConfig });
+ },
+ /**
+ * ** Delete Jobs for provided fixtures paths.
+ *
+ * @param {{relativePathToFixtures: Array<{pathToFixture:string;}>; optional?: boolean;}} taskConfig - configuration for task.
+ * relativePathToFixtures provides relative paths for fixtures files starting from directory fixtures
+ * optional if set to true will instruct the plugin to not log console error, if deletion status is different from 2xx, (e.g. 404 or 500)
+ * e.g. {
+ * relativePathToFixtures: [
+ * {
+ * pathToFixture: '/base/data-jobs/cy-e2e-vdk/cy-e2e-vdk-failing-v0.json'
+ * }
+ * ],
+ * optional: true
+ * }
+ * @returns {Promise}
+ */
+ deleteJobsFixtures: (taskConfig) => {
+ return deleteJobsFixtures(taskConfig, { ...cypressConfig });
+ },
+ /**
+ * ** Delete Data jobs if they exist.
+ *
+ * @param {Array<{job_name:string; description:string; team:string; config:{db_default_type:string; contacts:{}; schedule:{schedule_cron:string}; generate_keytab:boolean; enable_execution_notifications:boolean}}>} jobFixtures
+ * @param {Cypress.ResolvedConfigOptions} config
+ * @returns {Promise}
+ */
+ deleteJobs: ({ jobFixtures }) => {
+ return deleteJobs(jobFixtures, { ...cypressConfig });
+ },
+ /**
+ * ** Get JWT access token asynchronous.
+ */
+ getAccessToken: getAccessTokenAsynchronous,
+ /**
+ * ** Set JWT access token asynchronous.
+ */
+ setAccessToken: setAccessTokenAsynchronous,
+ /**
+ * ** Generate UUID.
+ *
+ * @returns {Cypress.Chainable<{uuid: string}>}
+ */
+ generateUUID: () => {
+ return generateUUID(true);
+ },
+ };
- // `on` is used to hook into various events Cypress emits
- on('task', TASKS);
+ // `on` is used to hook into various events Cypress emits
+ on("task", TASKS);
- const options = {
- outputRoot: cypressConfig.env.CYPRESS_TERMINAL_LOGS,
- // Used to trim the base path of specs and reduce nesting in the
- // generated output directory.
- specRoot: path.relative(cypressConfig.fileServerFolder, cypressConfig.integrationFolder),
- outputTarget: {
- 'cypress-logs|json': 'json'
- },
- printLogsToConsole: 'always',
- printLogsToFile: 'always',
- includeSuccessfulHookLogs: true,
- logToFilesOnAfterRun: true
- };
+ const options = {
+ outputRoot: cypressConfig.env.CYPRESS_TERMINAL_LOGS,
+ // Used to trim the base path of specs and reduce nesting in the
+ // generated output directory.
+ specRoot: path.relative(
+ cypressConfig.fileServerFolder,
+ cypressConfig.integrationFolder,
+ ),
+ outputTarget: {
+ "cypress-logs|json": "json",
+ },
+ printLogsToConsole: "always",
+ printLogsToFile: "always",
+ includeSuccessfulHookLogs: true,
+ logToFilesOnAfterRun: true,
+ };
- require('cypress-terminal-report/src/installLogsPrinter')(on, options);
- install(on, cypressConfig);
+ require("cypress-terminal-report/src/installLogsPrinter")(on, options);
+ install(on, cypressConfig);
- on('before:browser:launch', (browser = {}, launchOptions) => {
- ensureBrowserFlags(browser, launchOptions);
- return launchOptions;
- });
+ on("before:browser:launch", (browser = {}, launchOptions) => {
+ ensureBrowserFlags(browser, launchOptions);
+ return launchOptions;
+ });
};
diff --git a/projects/frontend/data-pipelines/gui/e2e/support/commands.js b/projects/frontend/data-pipelines/gui/e2e/support/commands.js
index 6547a3ef71..07126ef6c8 100644
--- a/projects/frontend/data-pipelines/gui/e2e/support/commands.js
+++ b/projects/frontend/data-pipelines/gui/e2e/support/commands.js
@@ -5,10 +5,15 @@
///
-import 'cypress-localstorage-commands';
+import "cypress-localstorage-commands";
-import { parseJWTToken } from '../plugins/helpers/util-helpers.plugins';
-import { BASIC_AUTH_CONFIG, CSP_ACCESS_TOKEN_KEY, CSP_EXPIRES_AT_KEY, CSP_ID_TOKEN_KEY } from './helpers/constants.support';
+import { parseJWTToken } from "../plugins/helpers/util-helpers.plugins";
+import {
+ BASIC_AUTH_CONFIG,
+ CSP_ACCESS_TOKEN_KEY,
+ CSP_EXPIRES_AT_KEY,
+ CSP_ID_TOKEN_KEY,
+} from "./helpers/constants.support";
let jwtToken;
let idToken;
@@ -24,256 +29,283 @@ let expiresAt;
// });
const _persistCspDataToStorage = (payload) => {
- if (payload) {
- idToken = payload.id_token;
- accessToken = payload.access_token;
- expiresAt = JSON.stringify(Date.now() + payload.expires_in * 1000);
- }
-
- window.localStorage.setItem(CSP_ID_TOKEN_KEY, idToken);
- window.localStorage.setItem(CSP_ACCESS_TOKEN_KEY, accessToken);
- window.localStorage.setItem(CSP_EXPIRES_AT_KEY, expiresAt);
-
- // Set the CSP token in the session storage to enable the Integration testing against Management UI
- sessionStorage.setItem(CSP_ID_TOKEN_KEY, idToken);
- sessionStorage.setItem(CSP_ACCESS_TOKEN_KEY, accessToken);
- sessionStorage.setItem(CSP_EXPIRES_AT_KEY, expiresAt);
+ if (payload) {
+ idToken = payload.id_token;
+ accessToken = payload.access_token;
+ expiresAt = JSON.stringify(Date.now() + payload.expires_in * 1000);
+ }
+
+ window.localStorage.setItem(CSP_ID_TOKEN_KEY, idToken);
+ window.localStorage.setItem(CSP_ACCESS_TOKEN_KEY, accessToken);
+ window.localStorage.setItem(CSP_EXPIRES_AT_KEY, expiresAt);
+
+ // Set the CSP token in the session storage to enable the Integration testing against Management UI
+ sessionStorage.setItem(CSP_ID_TOKEN_KEY, idToken);
+ sessionStorage.setItem(CSP_ACCESS_TOKEN_KEY, accessToken);
+ sessionStorage.setItem(CSP_EXPIRES_AT_KEY, expiresAt);
};
-Cypress.Commands.add('login', () => {
- cy.log('Requesting JWT Token with refresh token');
-
- return cy
+Cypress.Commands.add("login", () => {
+ cy.log("Requesting JWT Token with refresh token");
+
+ return cy
+ .request({
+ followRedirect: false,
+ failOnStatusCode: false,
+ method: "POST",
+ // See project README.md how to set this login url
+ url: `${Cypress.env("csp_url")}/csp/gateway/am/api/auth/api-tokens/authorize`,
+ form: true,
+ headers: {
+ // CSP staging is using CloudFront CDN that does not permit bot requests unless the below user agent is set
+ "user-agent": "csp-automation-tests",
+ },
+ body: {
+ // See project README.md how to set this token
+ api_token: Cypress.env("OAUTH2_API_TOKEN"),
+ },
+ })
+ .its("body")
+ .then(($body) => {
+ const decodedAccessToken = parseJWTToken($body.access_token);
+
+ if (!decodedAccessToken.claims.ovl) {
+ return {
+ ...$body,
+ decoded_access_token: decodedAccessToken,
+ };
+ }
+
+ cy.log("Requesting claims expansion");
+
+ return cy
.request({
- followRedirect: false,
- failOnStatusCode: false,
- method: 'POST',
- // See project README.md how to set this login url
- url: `${Cypress.env('csp_url')}/csp/gateway/am/api/auth/api-tokens/authorize`,
- form: true,
- headers: {
- // CSP staging is using CloudFront CDN that does not permit bot requests unless the below user agent is set
- 'user-agent': 'csp-automation-tests'
- },
- body: {
- // See project README.md how to set this token
- api_token: Cypress.env('OAUTH2_API_TOKEN')
- }
- })
- .its('body')
- .then(($body) => {
- const decodedAccessToken = parseJWTToken($body.access_token);
-
- if (!decodedAccessToken.claims.ovl) {
- return {
- ...$body,
- decoded_access_token: decodedAccessToken
- };
- }
-
- cy.log('Requesting claims expansion');
-
- return cy
- .request({
- method: 'GET',
- url: `${Cypress.env('csp_url')}/csp/gateway/am/api/auth/token/expand-overflow-claims`,
- headers: {
- Authorization: `Bearer ${$body.access_token}`,
- // CSP staging is using CloudFront CDN that does not permit bot requests unless the below user agent is set
- 'user-agent': 'csp-automation-tests'
- }
- })
- .its('body')
- .then((claims) => {
- return {
- ...$body,
- decoded_access_token: {
- ...decodedAccessToken,
- claims
- }
- };
- });
+ method: "GET",
+ url: `${Cypress.env("csp_url")}/csp/gateway/am/api/auth/token/expand-overflow-claims`,
+ headers: {
+ Authorization: `Bearer ${$body.access_token}`,
+ // CSP staging is using CloudFront CDN that does not permit bot requests unless the below user agent is set
+ "user-agent": "csp-automation-tests",
+ },
})
- .then((body) => {
- jwtToken = JSON.stringify(body);
+ .its("body")
+ .then((claims) => {
+ return {
+ ...$body,
+ decoded_access_token: {
+ ...decodedAccessToken,
+ claims,
+ },
+ };
+ });
+ })
+ .then((body) => {
+ jwtToken = JSON.stringify(body);
- _persistCspDataToStorage(body);
+ _persistCspDataToStorage(body);
- cy.task('setAccessToken', accessToken);
+ cy.task("setAccessToken", accessToken);
- cy.log('Logged in successfully.');
+ cy.log("Logged in successfully.");
- return cy.wrap({
- context: 'commands::login()',
- action: 'continue'
- });
- });
+ return cy.wrap({
+ context: "commands::login()",
+ action: "continue",
+ });
+ });
});
-Cypress.Commands.add('wireUserSession', () => {
- if (jwtToken) {
- _persistCspDataToStorage();
+Cypress.Commands.add("wireUserSession", () => {
+ if (jwtToken) {
+ _persistCspDataToStorage();
- return cy.wrap({
- context: 'commands::1::wireUserSession()',
- action: 'continue'
- });
- }
+ return cy.wrap({
+ context: "commands::1::wireUserSession()",
+ action: "continue",
+ });
+ }
- return cy.login();
+ return cy.login();
});
-Cypress.Commands.add('recordHarIfSupported', () => {
- if (Cypress.browser.name === 'chrome') {
- return cy.recordHar({
- excludePaths: [
- // exclude from dev build vendor, scripts and polyfills bundles
- /(vendor|scripts|polyfills)\.js$/,
-
- // exclude from dev/prod clarity styles
- /clr-ui\.min\.css$/,
-
- // exclude global and grafana styles
- /(styles|grafana.light)(\..*)?\.css$/,
-
- // exclude woff2 fonts
- /.*\.woff2/,
-
- // SuperCollider js
- // exclude from prod build
- // main bundle "main.xyz.js"
- // scripts bundle "scripts.xyz.js"
- // polyfills bundle "polyfills.xyz.js"
- // runtime bundle "runtime.xyz.js"
- // lazy loaded modules "199.xyz.js"
- /(main|scripts|polyfills|runtime|\d+)(\..*)?\.js$/,
-
- // Grafana embedded panel js
- // vendors app bundle "vendors-app.xyz.js"
- // app bundle "app.xyz.js"
- // moment-app bundle "moment-app.xyz.js"
- // angular-app bundle "angular-app.xyz.js"
- // influxdbPlugin bundle "influxdbPlugin.xyz.js"
- // SoloPanelPage bundle "SoloPanelPage.xyz.js"
- /(vendors-app|app|moment-app|angular-app|influxdbPlugin|SoloPanelPage)(\..*)?\.js$/
- ]
- });
- }
-
- return cy.wrap({
- context: 'commands::recordHarIfSupported()',
- action: 'continue'
+Cypress.Commands.add("recordHarIfSupported", () => {
+ if (Cypress.browser.name === "chrome") {
+ return cy.recordHar({
+ excludePaths: [
+ // exclude from dev build vendor, scripts and polyfills bundles
+ /(vendor|scripts|polyfills)\.js$/,
+
+ // exclude from dev/prod clarity styles
+ /clr-ui\.min\.css$/,
+
+ // exclude global and grafana styles
+ /(styles|grafana.light)(\..*)?\.css$/,
+
+ // exclude woff2 fonts
+ /.*\.woff2/,
+
+ // SuperCollider js
+ // exclude from prod build
+ // main bundle "main.xyz.js"
+ // scripts bundle "scripts.xyz.js"
+ // polyfills bundle "polyfills.xyz.js"
+ // runtime bundle "runtime.xyz.js"
+ // lazy loaded modules "199.xyz.js"
+ /(main|scripts|polyfills|runtime|\d+)(\..*)?\.js$/,
+
+ // Grafana embedded panel js
+ // vendors app bundle "vendors-app.xyz.js"
+ // app bundle "app.xyz.js"
+ // moment-app bundle "moment-app.xyz.js"
+ // angular-app bundle "angular-app.xyz.js"
+ // influxdbPlugin bundle "influxdbPlugin.xyz.js"
+ // SoloPanelPage bundle "SoloPanelPage.xyz.js"
+ /(vendors-app|app|moment-app|angular-app|influxdbPlugin|SoloPanelPage)(\..*)?\.js$/,
+ ],
});
+ }
+
+ return cy.wrap({
+ context: "commands::recordHarIfSupported()",
+ action: "continue",
+ });
});
-Cypress.Commands.add('saveHarIfSupported', () => {
- if (Cypress.browser.name === 'chrome') {
- return cy.saveHar();
- }
+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",
+ });
});
// CSP
-Cypress.Commands.add('initCspLoggedUserProfileGetReqInterceptor', () => {
- return cy.intercept('GET', '**/csp/gateway/am/api/auth/token-public-key?format=jwks').as('cspLoggedUserProfileGetReq');
+Cypress.Commands.add("initCspLoggedUserProfileGetReqInterceptor", () => {
+ return cy
+ .intercept("GET", "**/csp/gateway/am/api/auth/token-public-key?format=jwks")
+ .as("cspLoggedUserProfileGetReq");
});
-Cypress.Commands.add('waitForCspLoggedUserProfileGetReqInterceptor', () => {
- return cy.wait('@cspLoggedUserProfileGetReq');
+Cypress.Commands.add("waitForCspLoggedUserProfileGetReqInterceptor", () => {
+ return cy.wait("@cspLoggedUserProfileGetReq");
});
// Data Pipelines
-Cypress.Commands.add('initDataJobsApiGetReqInterceptor', () => {
- return cy.intercept('GET', '**/data-jobs/for-team/**').as('dataJobsApiGetReq');
+Cypress.Commands.add("initDataJobsApiGetReqInterceptor", () => {
+ return cy
+ .intercept("GET", "**/data-jobs/for-team/**")
+ .as("dataJobsApiGetReq");
});
-Cypress.Commands.add('waitForDataJobsApiGetReqInterceptor', () => {
- return cy.wait('@dataJobsApiGetReq');
+Cypress.Commands.add("waitForDataJobsApiGetReqInterceptor", () => {
+ return cy.wait("@dataJobsApiGetReq");
});
-Cypress.Commands.add('initDataJobsExecutionsGetReqInterceptor', () => {
- return cy.intercept('GET', '**/data-jobs/for-team/**', (req) => {
- if (req && req.query && req.query.query && req.query.operationName === 'jobsQuery' && req.query.query.includes('executions') && req.query.query.includes('DataJobExecutionFilter') && req.query.query.includes('DataJobExecutionOrder')) {
- req.alias = 'dataJobsExecutionsGetReq';
- }
+Cypress.Commands.add("initDataJobsExecutionsGetReqInterceptor", () => {
+ return cy.intercept("GET", "**/data-jobs/for-team/**", (req) => {
+ if (
+ req &&
+ req.query &&
+ req.query.query &&
+ req.query.operationName === "jobsQuery" &&
+ req.query.query.includes("executions") &&
+ req.query.query.includes("DataJobExecutionFilter") &&
+ req.query.query.includes("DataJobExecutionOrder")
+ ) {
+ req.alias = "dataJobsExecutionsGetReq";
+ }
- return req;
- });
+ return req;
+ });
});
-Cypress.Commands.add('initDataJobsSingleExecutionGetReqInterceptor', () => {
- return cy.intercept('GET', '**/data-jobs/for-team/**/executions/**').as('dataJobsSingleExecutionGetReq');
+Cypress.Commands.add("initDataJobsSingleExecutionGetReqInterceptor", () => {
+ return cy
+ .intercept("GET", "**/data-jobs/for-team/**/executions/**")
+ .as("dataJobsSingleExecutionGetReq");
});
-Cypress.Commands.add('initDataJobExecutionPostReqInterceptor', () => {
- return cy.intercept('POST', '**/data-jobs/for-team/**/executions').as('dataJobExecutionPostReq');
+Cypress.Commands.add("initDataJobExecutionPostReqInterceptor", () => {
+ return cy
+ .intercept("POST", "**/data-jobs/for-team/**/executions")
+ .as("dataJobExecutionPostReq");
});
-Cypress.Commands.add('waitForDataJobExecutionPostReqInterceptor', () => {
- return cy.wait('@dataJobExecutionPostReq');
+Cypress.Commands.add("waitForDataJobExecutionPostReqInterceptor", () => {
+ return cy.wait("@dataJobExecutionPostReq");
});
-Cypress.Commands.add('initDataJobExecutionDeleteReqInterceptor', () => {
- return cy.intercept('DELETE', '**/data-jobs/for-team/**/executions/**').as('dataJobExecutionDeleteReq');
+Cypress.Commands.add("initDataJobExecutionDeleteReqInterceptor", () => {
+ return cy
+ .intercept("DELETE", "**/data-jobs/for-team/**/executions/**")
+ .as("dataJobExecutionDeleteReq");
});
-Cypress.Commands.add('waitForDataJobExecutionDeleteReqInterceptor', () => {
- return cy.wait('@dataJobExecutionDeleteReq');
+Cypress.Commands.add("waitForDataJobExecutionDeleteReqInterceptor", () => {
+ return cy.wait("@dataJobExecutionDeleteReq");
});
-Cypress.Commands.add('initDataJobPutReqInterceptor', () => {
- return cy.intercept('PUT', '**/data-jobs/for-team/*/jobs/*').as('dataJobPutReq');
+Cypress.Commands.add("initDataJobPutReqInterceptor", () => {
+ return cy
+ .intercept("PUT", "**/data-jobs/for-team/*/jobs/*")
+ .as("dataJobPutReq");
});
-Cypress.Commands.add('waitForDataJobPutReqInterceptor', () => {
- return cy.wait('@dataJobPutReq');
+Cypress.Commands.add("waitForDataJobPutReqInterceptor", () => {
+ return cy.wait("@dataJobPutReq");
});
-Cypress.Commands.add('initDataJobDeleteReqInterceptor', () => {
- return cy.intercept('DELETE', '**/data-jobs/for-team/**/jobs/**').as('dataJobDeleteReq');
+Cypress.Commands.add("initDataJobDeleteReqInterceptor", () => {
+ return cy
+ .intercept("DELETE", "**/data-jobs/for-team/**/jobs/**")
+ .as("dataJobDeleteReq");
});
-Cypress.Commands.add('waitForDataJobDeleteReqInterceptor', () => {
- return cy.wait('@dataJobDeleteReq');
+Cypress.Commands.add("waitForDataJobDeleteReqInterceptor", () => {
+ return cy.wait("@dataJobDeleteReq");
});
-Cypress.Commands.add('initDataJobDeploymentPatchReqInterceptor', () => {
- return cy.intercept('PATCH', '**/data-jobs/for-team/**/deployments/**').as('dataJobDeploymentPatchReq');
+Cypress.Commands.add("initDataJobDeploymentPatchReqInterceptor", () => {
+ return cy
+ .intercept("PATCH", "**/data-jobs/for-team/**/deployments/**")
+ .as("dataJobDeploymentPatchReq");
});
-Cypress.Commands.add('waitForDataJobDeploymentPatchReqInterceptor', () => {
- return cy.wait('@dataJobDeploymentPatchReq');
+Cypress.Commands.add("waitForDataJobDeploymentPatchReqInterceptor", () => {
+ return cy.wait("@dataJobDeploymentPatchReq");
});
// Generics
-Cypress.Commands.add('waitForInterceptorWithRetry', (aliasName, retries, config) => {
+Cypress.Commands.add(
+ "waitForInterceptorWithRetry",
+ (aliasName, retries, config) => {
return cy.wait(aliasName).then((interception) => {
- if (config.predicate(interception)) {
- if (typeof config.onfulfill === 'function') {
- config.onfulfill(interception);
- }
-
- return cy.wrap(interception);
+ if (config.predicate(interception)) {
+ if (typeof config.onfulfill === "function") {
+ config.onfulfill(interception);
}
- if (retries > 0) {
- return cy.waitForInterceptorWithRetry(aliasName, retries - 1, config);
- }
+ return cy.wrap(interception);
+ }
+
+ if (retries > 0) {
+ return cy.waitForInterceptorWithRetry(aliasName, retries - 1, config);
+ }
});
-});
+ },
+);
// App Config
-Cypress.Commands.add('appConfigInterceptorDisableExploreRoute', () => {
- cy.intercept('GET', '/assets/data/appConfig.json', {
- auth: BASIC_AUTH_CONFIG,
- ignoreRoutes: ['explore/data-jobs', 'explore/data-jobs/:team/:job'],
- ignoreComponents: ['explorePage']
- });
+Cypress.Commands.add("appConfigInterceptorDisableExploreRoute", () => {
+ cy.intercept("GET", "/assets/data/appConfig.json", {
+ auth: BASIC_AUTH_CONFIG,
+ ignoreRoutes: ["explore/data-jobs", "explore/data-jobs/:team/:job"],
+ ignoreComponents: ["explorePage"],
+ });
});
diff --git a/projects/frontend/data-pipelines/gui/e2e/support/helpers/constants.support.js b/projects/frontend/data-pipelines/gui/e2e/support/helpers/constants.support.js
index 35d800de4c..6a16db9a63 100644
--- a/projects/frontend/data-pipelines/gui/e2e/support/helpers/constants.support.js
+++ b/projects/frontend/data-pipelines/gui/e2e/support/helpers/constants.support.js
@@ -9,31 +9,31 @@
* ** CSP Id token key.
* @type {string}
*/
-const CSP_ID_TOKEN_KEY = 'id_token';
+const CSP_ID_TOKEN_KEY = "id_token";
/**
* ** CSP Access token key.
* @type {string}
*/
-const CSP_ACCESS_TOKEN_KEY = 'access_token';
+const CSP_ACCESS_TOKEN_KEY = "access_token";
/**
* ** CSP Token expires at key.
* @type {string}
*/
-const CSP_EXPIRES_AT_KEY = 'expires_at';
+const CSP_EXPIRES_AT_KEY = "expires_at";
/**
* ** Long-lived Team that owns Data jobs for Data Pipelines feature.
* @type {'cy-e2e-vdk'}
*/
-const TEAM_VDK = 'cy-e2e-vdk';
+const TEAM_VDK = "cy-e2e-vdk";
/**
* ** Long-lived Data job name owned from {@link: TEAM_VDK}
* @type {'cy-e2e-vdk-failing-v0'}
*/
-const TEAM_VDK_DATA_JOB_FAILING = 'cy-e2e-vdk-failing-v0';
+const TEAM_VDK_DATA_JOB_FAILING = "cy-e2e-vdk-failing-v0";
/**
* ** Short-lived Test Data job name v0 owned from {@link: TEAM_VDK} created in tests and deleted after suite.
@@ -42,7 +42,7 @@ const TEAM_VDK_DATA_JOB_FAILING = 'cy-e2e-vdk-failing-v0';
*
* @type {'cy-e2e-vdk-test-v0'}
*/
-const TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V0 = 'cy-e2e-vdk-test-v0';
+const TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V0 = "cy-e2e-vdk-test-v0";
/**
* ** Short-lived Test Data job name v1 owned from {@link: TEAM_VDK} created in tests and deleted after suite.
@@ -51,7 +51,7 @@ const TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V0 = 'cy-e2e-vdk-test-v0';
*
* @type {'cy-e2e-vdk-test-v1'}
*/
-const TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V1 = 'cy-e2e-vdk-test-v1';
+const TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V1 = "cy-e2e-vdk-test-v1";
/**
* ** Short-lived Test Data job name v2 owned from {@link: TEAM_VDK} created in tests and deleted after suite.
@@ -60,7 +60,7 @@ const TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V1 = 'cy-e2e-vdk-test-v1';
*
* @type {'cy-e2e-vdk-test-v2'}
*/
-const TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V2 = 'cy-e2e-vdk-test-v2';
+const TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V2 = "cy-e2e-vdk-test-v2";
/**
* ** Short-lived Test Data job name v10 owned from {@link: TEAM_VDK} created in tests and deleted after suite.
@@ -69,7 +69,7 @@ const TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V2 = 'cy-e2e-vdk-test-v2';
*
* @type {'cy-e2e-vdk-test-v10'}
*/
-const TEAM_VDK_DATA_JOB_TEST_V10 = 'cy-e2e-vdk-test-v10';
+const TEAM_VDK_DATA_JOB_TEST_V10 = "cy-e2e-vdk-test-v10";
/**
* ** Short-lived Test Data job name v11 owned from {@link: TEAM_VDK} created in tests and deleted after suite.
@@ -78,7 +78,7 @@ const TEAM_VDK_DATA_JOB_TEST_V10 = 'cy-e2e-vdk-test-v10';
*
* @type {'cy-e2e-vdk-test-v11'}
*/
-const TEAM_VDK_DATA_JOB_TEST_V11 = 'cy-e2e-vdk-test-v11';
+const TEAM_VDK_DATA_JOB_TEST_V11 = "cy-e2e-vdk-test-v11";
/**
* ** Short-lived Test Data job name v12 owned from {@link: TEAM_VDK} created in tests and deleted after suite.
@@ -87,53 +87,58 @@ const TEAM_VDK_DATA_JOB_TEST_V11 = 'cy-e2e-vdk-test-v11';
*
* @type {'cy-e2e-vdk-test-v12'}
*/
-const TEAM_VDK_DATA_JOB_TEST_V12 = 'cy-e2e-vdk-test-v12';
+const TEAM_VDK_DATA_JOB_TEST_V12 = "cy-e2e-vdk-test-v12";
const BASIC_AUTH_CONFIG = {
- consoleCloudUrl: 'https://console-stg.cloud.vmware.com/',
- orgLinkRoot: '/csp/gateway/am/api/orgs/',
- authConfig: {
- issuer: 'https://console-stg.cloud.vmware.com/csp/gateway/am/api/',
- redirectUri: '$window.location.origin/',
- skipIssuerCheck: true,
- requestAccessToken: true,
- oidc: true,
- strictDiscoveryDocumentValidation: false,
- clientId: '8qQgcmhhsXuhGJs58ZW1hQ86h3eZXTpBV6t',
- responseType: 'code',
- scope: 'openid ALL_PERMISSIONS customer_number group_names',
- showDebugInformation: true,
- silentRefreshRedirectUri: '$window.location.origin/silent-refresh.html',
- useSilentRefresh: true,
- silentRefreshTimeout: 5000,
- timeoutFactor: 0.25,
- sessionChecksEnabled: true,
- clearHashAfterLogin: false,
- logoutUrl: 'https://console-stg.cloud.vmware.com/csp/gateway/discovery?logout',
- nonceStateSeparator: 'semicolon'
- },
- resourceServer: {
- allowedUrls: ['https://console-stg.cloud.vmware.com/', 'https://gaz-preview.csp-vidm-prod.com/', '/data-jobs'],
- sendAccessToken: true
- },
- refreshTokenConfig: {
- start: 500,
- remainingTime: 360,
- checkInterval: 60
- }
+ consoleCloudUrl: "https://console-stg.cloud.vmware.com/",
+ orgLinkRoot: "/csp/gateway/am/api/orgs/",
+ authConfig: {
+ issuer: "https://console-stg.cloud.vmware.com/csp/gateway/am/api/",
+ redirectUri: "$window.location.origin/",
+ skipIssuerCheck: true,
+ requestAccessToken: true,
+ oidc: true,
+ strictDiscoveryDocumentValidation: false,
+ clientId: "8qQgcmhhsXuhGJs58ZW1hQ86h3eZXTpBV6t",
+ responseType: "code",
+ scope: "openid ALL_PERMISSIONS customer_number group_names",
+ showDebugInformation: true,
+ silentRefreshRedirectUri: "$window.location.origin/silent-refresh.html",
+ useSilentRefresh: true,
+ silentRefreshTimeout: 5000,
+ timeoutFactor: 0.25,
+ sessionChecksEnabled: true,
+ clearHashAfterLogin: false,
+ logoutUrl:
+ "https://console-stg.cloud.vmware.com/csp/gateway/discovery?logout",
+ nonceStateSeparator: "semicolon",
+ },
+ resourceServer: {
+ allowedUrls: [
+ "https://console-stg.cloud.vmware.com/",
+ "https://gaz-preview.csp-vidm-prod.com/",
+ "/data-jobs",
+ ],
+ sendAccessToken: true,
+ },
+ refreshTokenConfig: {
+ start: 500,
+ remainingTime: 360,
+ checkInterval: 60,
+ },
};
module.exports = {
- BASIC_AUTH_CONFIG,
- CSP_ID_TOKEN_KEY,
- CSP_ACCESS_TOKEN_KEY,
- CSP_EXPIRES_AT_KEY,
- TEAM_VDK,
- TEAM_VDK_DATA_JOB_FAILING,
- TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V0,
- TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V1,
- TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V2,
- TEAM_VDK_DATA_JOB_TEST_V10,
- TEAM_VDK_DATA_JOB_TEST_V11,
- TEAM_VDK_DATA_JOB_TEST_V12
+ BASIC_AUTH_CONFIG,
+ CSP_ID_TOKEN_KEY,
+ CSP_ACCESS_TOKEN_KEY,
+ CSP_EXPIRES_AT_KEY,
+ TEAM_VDK,
+ TEAM_VDK_DATA_JOB_FAILING,
+ TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V0,
+ TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V1,
+ TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V2,
+ TEAM_VDK_DATA_JOB_TEST_V10,
+ TEAM_VDK_DATA_JOB_TEST_V11,
+ TEAM_VDK_DATA_JOB_TEST_V12,
};
diff --git a/projects/frontend/data-pipelines/gui/e2e/support/index.js b/projects/frontend/data-pipelines/gui/e2e/support/index.js
index 98f58cbf51..f49fa2dd22 100644
--- a/projects/frontend/data-pipelines/gui/e2e/support/index.js
+++ b/projects/frontend/data-pipelines/gui/e2e/support/index.js
@@ -19,33 +19,41 @@
// ***********************************************************
// Import commands.js using ES2015 syntax:
-import './commands';
+import "./commands";
-require('@neuralegion/cypress-har-generator/commands');
+require("@neuralegion/cypress-har-generator/commands");
-const CYPRESS_GREP = require('cypress-grep');
-const CYPRESS_TERMINAL = require('cypress-terminal-report/src/installLogsCollector');
+const CYPRESS_GREP = require("cypress-grep");
+const CYPRESS_TERMINAL = require("cypress-terminal-report/src/installLogsCollector");
CYPRESS_GREP();
-const CYPRESS_TERMINAL_ERROR_BLACKLIST = ['NG0100: ExpressionChangedAfterItHasBeenCheckedError', '"url": "https://console-stg.cloud.vmware.com/csp/gateway/slc/api/principal/org/service-families"', 'error loading jwks,'];
+const CYPRESS_TERMINAL_ERROR_BLACKLIST = [
+ "NG0100: ExpressionChangedAfterItHasBeenCheckedError",
+ '"url": "https://console-stg.cloud.vmware.com/csp/gateway/slc/api/principal/org/service-families"',
+ "error loading jwks,",
+];
CYPRESS_TERMINAL({
- filterLog: ([logType, message, severity]) => {
- if (logType !== 'cons:error') {
- return true;
- }
-
- return severity !== 'error' || !message || !CYPRESS_TERMINAL_ERROR_BLACKLIST.some((value) => message.includes(value));
+ filterLog: ([logType, message, severity]) => {
+ if (logType !== "cons:error") {
+ return true;
}
+
+ return (
+ severity !== "error" ||
+ !message ||
+ !CYPRESS_TERMINAL_ERROR_BLACKLIST.some((value) => message.includes(value))
+ );
+ },
});
Cypress.Server.defaults({
- delay: 500,
- force404: false,
- ignore: (xhr) => {
- return true;
- }
+ delay: 500,
+ force404: false,
+ ignore: (xhr) => {
+ return true;
+ },
});
// Alternatively you can use CommonJS syntax:
diff --git a/projects/frontend/data-pipelines/gui/e2e/support/pages/base/base-page.po.js b/projects/frontend/data-pipelines/gui/e2e/support/pages/base/base-page.po.js
index 4869b97cd3..a4f301a755 100644
--- a/projects/frontend/data-pipelines/gui/e2e/support/pages/base/base-page.po.js
+++ b/projects/frontend/data-pipelines/gui/e2e/support/pages/base/base-page.po.js
@@ -5,660 +5,706 @@
///
-const path = require('path');
+const path = require("path");
/**
* ** Base page superclass of all page objects classes.
*/
export class BasePagePO {
- static WAIT_AFTER_API_MODIFY_CALL = 1000; // ms
- static WAIT_SMART_DELAY = 250; // ms
- static WAIT_CLICK_THINK_TIME = 500; // ms
- static WAIT_VIEW_TO_RENDER_SHORT = 600; // ms
- static WAIT_VIEW_TO_RENDER_BASE = 1000; // ms
- static WAIT_MODAL_TO_RENDER_BASE = 500; //ms
- static WAIT_ACTION_THINK_TIME = 750; // ms
- static WAIT_INITIAL_PAGE_LOAD = 2 * 1000; // ms (2s)
- static WAIT_BEFORE_SUITE_START = 1.5 * 1000; // ms (1.5s)
- static WAIT_SHORT_TASK = 60 * 1000; // ms (1m)
- static WAIT_MEDIUM_TASK = 3 * 60 * 1000; // ms (3m)
- static WAIT_LONG_TASK = 5 * 60 * 1000; // ms (5m)
- static WAIT_EXTRA_LONG_TASK = 10 * 60 * 1000; // ms (10m)
-
- // Generics
-
- /**
- * ** Acquire JWT access token from CSP console API and return Chainable.
- *
- * @returns {Cypress.Chainable}
- */
- static login() {
- return this.executeCypressCommand('login');
- }
-
- /**
- ** Wire user session when reattach auth cookies if exist otherwise request auth token and then set auth cookies.
- *
- * @returns {Cypress.Chainable}
- */
- static wireUserSession() {
- return this.executeCypressCommand('wireUserSession');
- }
-
- /**
- * ** Returns instance of the page object.
- */
- static getPage() {
- return new BasePagePO();
- }
-
- /**
- * ** Returns current browser Url.
- *
- * @param {number} timeout
- * @returns {Cypress.Chainable}
- */
- static getCurrentUrl(timeout) {
- return cy.url({
- timeout: timeout ?? Cypress.config().defaultCommandTimeout
- });
- }
-
- /**
- * ** Init Http requests interceptors.
- */
- static initInterceptors() {
- // CSP
- this.executeCypressCommand('initCspLoggedUserProfileGetReqInterceptor');
- // Data Pipelines
- this.executeCypressCommand('initDataJobsApiGetReqInterceptor');
- }
-
- /**
- * ** Navigate to some url.
- *
- * @param {string} url
- * @returns {Cypress.Chainable}
- */
- static navigateToUrl(url) {
- return cy.visit(url);
- }
-
- /**
- * ** Navigate to page object page url.
- */
- static navigateTo(..._args) {
- this.navigateToUrl('/');
-
- this.waitForApplicationBootstrap();
-
- return this.getPage();
- }
-
- static navigateToNoBootstrap() {
- this.navigateToUrl('/');
- this.waitForViewToRenderShort();
- return this.getPage();
- }
-
- /**
- * ** Navigate to page with provided nav link id through side menu navigation and return instance of page object.
- *
- * @param {string|null} navLinkId
- * @param {'openExplore'|'openManage'} sideNavCommand
- * @param {{before: () => void; after: () => void;}} interceptors
- */
- static navigateWithSideMenu(navLinkId = null, sideNavCommand = null, interceptors = null) {
- cy.visit('/');
-
- if (interceptors && typeof interceptors.before === 'function') {
- interceptors.before();
- } else {
- this.waitForApplicationBootstrap();
- }
-
- if (navLinkId) {
- const basePagePO = this.getPage();
-
- if (sideNavCommand === 'openExplore') {
- basePagePO.openSideMenuNavExplore();
- } else if (sideNavCommand === 'openManage') {
- basePagePO.openSideMenuNavManage();
- }
-
- basePagePO.navigateToPage(navLinkId);
- }
-
- if (interceptors && typeof interceptors.after === 'function') {
- interceptors.after();
+ static WAIT_AFTER_API_MODIFY_CALL = 1000; // ms
+ static WAIT_SMART_DELAY = 250; // ms
+ static WAIT_CLICK_THINK_TIME = 500; // ms
+ static WAIT_VIEW_TO_RENDER_SHORT = 600; // ms
+ static WAIT_VIEW_TO_RENDER_BASE = 1000; // ms
+ static WAIT_MODAL_TO_RENDER_BASE = 500; //ms
+ static WAIT_ACTION_THINK_TIME = 750; // ms
+ static WAIT_INITIAL_PAGE_LOAD = 2 * 1000; // ms (2s)
+ static WAIT_BEFORE_SUITE_START = 1.5 * 1000; // ms (1.5s)
+ static WAIT_SHORT_TASK = 60 * 1000; // ms (1m)
+ static WAIT_MEDIUM_TASK = 3 * 60 * 1000; // ms (3m)
+ static WAIT_LONG_TASK = 5 * 60 * 1000; // ms (5m)
+ static WAIT_EXTRA_LONG_TASK = 10 * 60 * 1000; // ms (10m)
+
+ // Generics
+
+ /**
+ * ** Acquire JWT access token from CSP console API and return Chainable.
+ *
+ * @returns {Cypress.Chainable}
+ */
+ static login() {
+ return this.executeCypressCommand("login");
+ }
+
+ /**
+ ** Wire user session when reattach auth cookies if exist otherwise request auth token and then set auth cookies.
+ *
+ * @returns {Cypress.Chainable}
+ */
+ static wireUserSession() {
+ return this.executeCypressCommand("wireUserSession");
+ }
+
+ /**
+ * ** Returns instance of the page object.
+ */
+ static getPage() {
+ return new BasePagePO();
+ }
+
+ /**
+ * ** Returns current browser Url.
+ *
+ * @param {number} timeout
+ * @returns {Cypress.Chainable}
+ */
+ static getCurrentUrl(timeout) {
+ return cy.url({
+ timeout: timeout ?? Cypress.config().defaultCommandTimeout,
+ });
+ }
+
+ /**
+ * ** Init Http requests interceptors.
+ */
+ static initInterceptors() {
+ // CSP
+ this.executeCypressCommand("initCspLoggedUserProfileGetReqInterceptor");
+ // Data Pipelines
+ this.executeCypressCommand("initDataJobsApiGetReqInterceptor");
+ }
+
+ /**
+ * ** Navigate to some url.
+ *
+ * @param {string} url
+ * @returns {Cypress.Chainable}
+ */
+ static navigateToUrl(url) {
+ return cy.visit(url);
+ }
+
+ /**
+ * ** Navigate to page object page url.
+ */
+ static navigateTo(..._args) {
+ this.navigateToUrl("/");
+
+ this.waitForApplicationBootstrap();
+
+ return this.getPage();
+ }
+
+ static navigateToNoBootstrap() {
+ this.navigateToUrl("/");
+ this.waitForViewToRenderShort();
+ return this.getPage();
+ }
+
+ /**
+ * ** Navigate to page with provided nav link id through side menu navigation and return instance of page object.
+ *
+ * @param {string|null} navLinkId
+ * @param {'openExplore'|'openManage'} sideNavCommand
+ * @param {{before: () => void; after: () => void;}} interceptors
+ */
+ static navigateWithSideMenu(
+ navLinkId = null,
+ sideNavCommand = null,
+ interceptors = null,
+ ) {
+ cy.visit("/");
+
+ if (interceptors && typeof interceptors.before === "function") {
+ interceptors.before();
+ } else {
+ this.waitForApplicationBootstrap();
+ }
+
+ if (navLinkId) {
+ const basePagePO = this.getPage();
+
+ if (sideNavCommand === "openExplore") {
+ basePagePO.openSideMenuNavExplore();
+ } else if (sideNavCommand === "openManage") {
+ basePagePO.openSideMenuNavManage();
+ }
+
+ basePagePO.navigateToPage(navLinkId);
+ }
+
+ if (interceptors && typeof interceptors.after === "function") {
+ interceptors.after();
+ }
+
+ return this.getPage();
+ }
+
+ /**
+ * ** Execute Cypress command.
+ *
+ * @param {string} cypressCommand
+ * @param {number | null} numberOfExecution
+ * @param {number | null} additionalWait
+ * @returns {Cypress.Chainable<{context: string, action: string}>|Cypress.Chainable}
+ */
+ static executeCypressCommand(
+ cypressCommand,
+ numberOfExecution = null,
+ additionalWait = null,
+ ) {
+ if (typeof numberOfExecution === "number") {
+ /**
+ * @type Cypress.Chainable
+ */
+ let lastCommand;
+
+ for (let i = 0; i < numberOfExecution; i++) {
+ lastCommand = cy[cypressCommand]();
+ }
+
+ if (typeof additionalWait === "number") {
+ return cy.wait(additionalWait);
+ }
+
+ if (lastCommand) {
+ return lastCommand;
+ }
+
+ return cy.wrap({
+ context: "BasePagePO::base-page.po::executeCypressCommand()",
+ action: "continue",
+ });
+ } else {
+ return cy[cypressCommand]().then(($value) => {
+ if (typeof additionalWait === "number") {
+ return cy.wait(additionalWait);
}
- return this.getPage();
- }
-
- /**
- * ** Execute Cypress command.
- *
- * @param {string} cypressCommand
- * @param {number | null} numberOfExecution
- * @param {number | null} additionalWait
- * @returns {Cypress.Chainable<{context: string, action: string}>|Cypress.Chainable}
- */
- static executeCypressCommand(cypressCommand, numberOfExecution = null, additionalWait = null) {
- if (typeof numberOfExecution === 'number') {
- /**
- * @type Cypress.Chainable
- */
- let lastCommand;
-
- for (let i = 0; i < numberOfExecution; i++) {
- lastCommand = cy[cypressCommand]();
- }
-
- if (typeof additionalWait === 'number') {
- return cy.wait(additionalWait);
+ return $value;
+ });
+ }
+ }
+
+ /**
+ * ** Wait for CSP logged user Get req interceptor completion.
+ *
+ * @param {number} additionalWait
+ * @return {Cypress.Chainable}
+ */
+ static waitForCspLoggedUserProfileGetReqInterceptor(additionalWait = 1000) {
+ return this.executeCypressCommand(
+ "waitForCspLoggedUserProfileGetReqInterceptor",
+ 1,
+ additionalWait,
+ );
+ }
+
+ /**
+ * ** Wait for Data Jobs req interceptor completion.
+ *
+ * @param {number} numberOfReqToWait
+ * @param {number} additionalWait
+ * @return {Cypress.Chainable}
+ */
+ static waitForDataJobsApiGetReqInterceptor(
+ numberOfReqToWait = 1,
+ additionalWait = 1000,
+ ) {
+ return this.executeCypressCommand(
+ "waitForDataJobsApiGetReqInterceptor",
+ numberOfReqToWait,
+ additionalWait,
+ );
+ }
+
+ /**
+ * ** Wait for Application bootstrap.
+ *
+ * @return {Cypress.Chainable}
+ */
+ static waitForApplicationBootstrap() {
+ return this.waitForCspLoggedUserProfileGetReqInterceptor(null)
+ .then(() => this.waitForViewToRenderShort())
+ .then(() => this.getMainContainer().should("exist"));
+ }
+
+ /**
+ * ** Wait for initial page load.
+ *
+ * @param {number} factor
+ * @return {Cypress.Chainable}
+ */
+ static waitForInitialPageLoad(factor = 1) {
+ return cy.wait(factor * BasePagePO.WAIT_INITIAL_PAGE_LOAD);
+ }
+
+ /**
+ * ** Wait for View to render.
+ *
+ * @param {number} factor
+ * @return {Cypress.Chainable}
+ */
+ static waitForViewToRender(factor = 1) {
+ return cy.wait(factor * BasePagePO.WAIT_VIEW_TO_RENDER_BASE);
+ }
+
+ /**
+ * ** Wait for View to render short.
+ *
+ * @param {number} factor
+ * @return {Cypress.Chainable}
+ */
+ static waitForViewToRenderShort(factor = 1) {
+ return cy.wait(factor * BasePagePO.WAIT_VIEW_TO_RENDER_SHORT);
+ }
+
+ /**
+ * ** Start HAR recording.
+ *
+ * @returns {Cypress.Chainable}
+ */
+ static recordHarIfSupported() {
+ return this.executeCypressCommand("recordHarIfSupported");
+ }
+
+ /**
+ * ** Save recorded HAR.
+ *
+ * @returns {Cypress.Chainable}
+ */
+ static saveHarIfSupported() {
+ return this.executeCypressCommand("saveHarIfSupported");
+ }
+
+ // Selectors
+
+ /**
+ * ** Get main container.
+ *
+ * @returns {Cypress.Chainable>}
+ */
+ static getMainContainer() {
+ return cy.get("[data-automation=vdk]", {
+ timeout: BasePagePO.WAIT_SHORT_TASK,
+ });
+ }
+
+ /**
+ * ** Wait for Data Jobs req interceptor completion.
+ *
+ * @param {number} numberOfReqToWait
+ * @return {Cypress.Chainable}
+ */
+ waitForDataJobsApiGetReqInterceptor(numberOfReqToWait = 1) {
+ return BasePagePO.waitForDataJobsApiGetReqInterceptor(numberOfReqToWait);
+ }
+
+ /**
+ * ** Wait smart delay.
+ *
+ * @param {number} factor
+ * @return {Cypress.Chainable}
+ */
+ waitForSmartDelay(factor = 1) {
+ return cy.wait(factor * BasePagePO.WAIT_SMART_DELAY); // ms
+ }
+
+ /**
+ * ** Wait Initial page load to finish.
+ *
+ * @param {number} factor
+ * @return {Cypress.Chainable}
+ */
+ waitForInitialPageLoad(factor = 1) {
+ return BasePagePO.waitForInitialPageLoad(factor); // ms
+ }
+
+ /**
+ * ** Wait for view to render
+ *
+ * @param {number} factor
+ * @return {Cypress.Chainable}
+ */
+ waitForViewToRender(factor = 1) {
+ return cy.wait(factor * BasePagePO.WAIT_VIEW_TO_RENDER_BASE); // ms
+ }
+
+ /**
+ * ** Wait for view to render
+ *
+ * @param {number} factor
+ * @return {Cypress.Chainable}
+ */
+ waitForViewToRenderShort(factor = 1) {
+ return cy.wait(factor * BasePagePO.WAIT_VIEW_TO_RENDER_SHORT); // ms
+ }
+
+ /**
+ * ** Wait for modal to render
+ *
+ * @param {number} factor
+ * @return {Cypress.Chainable}
+ */
+ waitForModalToRender(factor = 1) {
+ return cy.wait(factor * BasePagePO.WAIT_MODAL_TO_RENDER_BASE); // ms
+ }
+
+ /**
+ * ** Wait before click (something like thinking time in real env).
+ *
+ * @param {number} factor
+ * @return {Cypress.Chainable}
+ */
+ waitForClickThinkingTime(factor = 1) {
+ return cy.wait(factor * BasePagePO.WAIT_CLICK_THINK_TIME); // ms
+ }
+
+ /**
+ * ** Wait for generic action similar to click thinking time.
+ *
+ * @param {number} factor
+ * @return {Cypress.Chainable}
+ */
+ waitForActionThinkingTime(factor = 1) {
+ return cy.wait(factor * BasePagePO.WAIT_ACTION_THINK_TIME); // ms
+ }
+
+ /**
+ * ** Wait until Data grid is loaded.
+ *
+ * @param {string} contextSelector
+ * @param {number} timeout
+ * @returns {Cypress.Chainable}
+ */
+ waitForGridToLoad(contextSelector, timeout = BasePagePO.WAIT_SHORT_TASK) {
+ return cy
+ .get(`${contextSelector} clr-datagrid[data-automation=clr-grid-loaded]`, {
+ timeout: this.resolveTimeout(timeout),
+ })
+ .should("exist");
+ }
+
+ /**
+ * ** Returns current browser Url.
+ *
+ * @param {number} timeout
+ * @returns {Cypress.Chainable}
+ */
+ getCurrentUrl(timeout) {
+ return BasePagePO.getCurrentUrl(timeout);
+ }
+
+ /**
+ * ** Returns current browser Url normalized.
+ *
+ * @param {{includeUrl?: boolean; includeBaseUrl?: boolean; includePathSegment?: boolean; includeQueryString?: boolean; decodeQueryString?: boolean;}} extras
+ * @returns {Cypress.Chainable<{pathSegment: string; queryParams: {[key: string]: string}; baseUrl?: string; url?: string}>}
+ */
+ getCurrentUrlNormalized(extras = { includeQueryString: true }) {
+ return this.getCurrentUrl().then((locationHref) => {
+ const fullUrlSplit = locationHref.split("?");
+ const url = fullUrlSplit[0];
+ const queryString = fullUrlSplit[1] ?? "";
+ const pathSegment = url.replace(Cypress.config().baseUrl, "");
+
+ /**
+ * @type {{pathSegment: string; queryParams: {[key: string]: string}; baseUrl?: string; url?: string}}
+ */
+ const normalizedData = {};
+
+ if (extras.includeBaseUrl) {
+ normalizedData.baseUrl = Cypress.config().baseUrl;
+ }
+
+ if (extras.includeUrl) {
+ normalizedData.url = url;
+ }
+
+ if (extras.includePathSegment) {
+ normalizedData.pathSegment = `/${pathSegment.replace(/^\/+/, "")}`;
+ }
+
+ if (extras.includeQueryString) {
+ normalizedData.queryParams = queryString
+ .split("&")
+ .map((queryStringChunk) => {
+ if (queryStringChunk.length === 0) {
+ return {};
}
- if (lastCommand) {
- return lastCommand;
- }
-
- return cy.wrap({
- context: 'BasePagePO::base-page.po::executeCypressCommand()',
- action: 'continue'
- });
- } else {
- return cy[cypressCommand]().then(($value) => {
- if (typeof additionalWait === 'number') {
- return cy.wait(additionalWait);
- }
-
- return $value;
- });
- }
- }
-
- /**
- * ** Wait for CSP logged user Get req interceptor completion.
- *
- * @param {number} additionalWait
- * @return {Cypress.Chainable}
- */
- static waitForCspLoggedUserProfileGetReqInterceptor(additionalWait = 1000) {
- return this.executeCypressCommand('waitForCspLoggedUserProfileGetReqInterceptor', 1, additionalWait);
- }
-
- /**
- * ** Wait for Data Jobs req interceptor completion.
- *
- * @param {number} numberOfReqToWait
- * @param {number} additionalWait
- * @return {Cypress.Chainable}
- */
- static waitForDataJobsApiGetReqInterceptor(numberOfReqToWait = 1, additionalWait = 1000) {
- return this.executeCypressCommand('waitForDataJobsApiGetReqInterceptor', numberOfReqToWait, additionalWait);
- }
-
- /**
- * ** Wait for Application bootstrap.
- *
- * @return {Cypress.Chainable}
- */
- static waitForApplicationBootstrap() {
- return this.waitForCspLoggedUserProfileGetReqInterceptor(null)
- .then(() => this.waitForViewToRenderShort())
- .then(() => this.getMainContainer().should('exist'));
- }
-
- /**
- * ** Wait for initial page load.
- *
- * @param {number} factor
- * @return {Cypress.Chainable}
- */
- static waitForInitialPageLoad(factor = 1) {
- return cy.wait(factor * BasePagePO.WAIT_INITIAL_PAGE_LOAD);
- }
-
- /**
- * ** Wait for View to render.
- *
- * @param {number} factor
- * @return {Cypress.Chainable}
- */
- static waitForViewToRender(factor = 1) {
- return cy.wait(factor * BasePagePO.WAIT_VIEW_TO_RENDER_BASE);
- }
-
- /**
- * ** Wait for View to render short.
- *
- * @param {number} factor
- * @return {Cypress.Chainable}
- */
- static waitForViewToRenderShort(factor = 1) {
- return cy.wait(factor * BasePagePO.WAIT_VIEW_TO_RENDER_SHORT);
- }
-
- /**
- * ** Start HAR recording.
- *
- * @returns {Cypress.Chainable}
- */
- static recordHarIfSupported() {
- return this.executeCypressCommand('recordHarIfSupported');
- }
-
- /**
- * ** Save recorded HAR.
- *
- * @returns {Cypress.Chainable}
- */
- static saveHarIfSupported() {
- return this.executeCypressCommand('saveHarIfSupported');
- }
-
- // Selectors
-
- /**
- * ** Get main container.
- *
- * @returns {Cypress.Chainable>}
- */
- static getMainContainer() {
- return cy.get('[data-automation=vdk]', {
- timeout: BasePagePO.WAIT_SHORT_TASK
- });
- }
-
- /**
- * ** Wait for Data Jobs req interceptor completion.
- *
- * @param {number} numberOfReqToWait
- * @return {Cypress.Chainable}
- */
- waitForDataJobsApiGetReqInterceptor(numberOfReqToWait = 1) {
- return BasePagePO.waitForDataJobsApiGetReqInterceptor(numberOfReqToWait);
- }
-
- /**
- * ** Wait smart delay.
- *
- * @param {number} factor
- * @return {Cypress.Chainable}
- */
- waitForSmartDelay(factor = 1) {
- return cy.wait(factor * BasePagePO.WAIT_SMART_DELAY); // ms
- }
-
- /**
- * ** Wait Initial page load to finish.
- *
- * @param {number} factor
- * @return {Cypress.Chainable}
- */
- waitForInitialPageLoad(factor = 1) {
- return BasePagePO.waitForInitialPageLoad(factor); // ms
- }
-
- /**
- * ** Wait for view to render
- *
- * @param {number} factor
- * @return {Cypress.Chainable}
- */
- waitForViewToRender(factor = 1) {
- return cy.wait(factor * BasePagePO.WAIT_VIEW_TO_RENDER_BASE); // ms
- }
-
- /**
- * ** Wait for view to render
- *
- * @param {number} factor
- * @return {Cypress.Chainable}
- */
- waitForViewToRenderShort(factor = 1) {
- return cy.wait(factor * BasePagePO.WAIT_VIEW_TO_RENDER_SHORT); // ms
- }
-
- /**
- * ** Wait for modal to render
- *
- * @param {number} factor
- * @return {Cypress.Chainable}
- */
- waitForModalToRender(factor = 1) {
- return cy.wait(factor * BasePagePO.WAIT_MODAL_TO_RENDER_BASE); // ms
- }
-
- /**
- * ** Wait before click (something like thinking time in real env).
- *
- * @param {number} factor
- * @return {Cypress.Chainable}
- */
- waitForClickThinkingTime(factor = 1) {
- return cy.wait(factor * BasePagePO.WAIT_CLICK_THINK_TIME); // ms
- }
-
- /**
- * ** Wait for generic action similar to click thinking time.
- *
- * @param {number} factor
- * @return {Cypress.Chainable}
- */
- waitForActionThinkingTime(factor = 1) {
- return cy.wait(factor * BasePagePO.WAIT_ACTION_THINK_TIME); // ms
- }
-
- /**
- * ** Wait until Data grid is loaded.
- *
- * @param {string} contextSelector
- * @param {number} timeout
- * @returns {Cypress.Chainable}
- */
- waitForGridToLoad(contextSelector, timeout = BasePagePO.WAIT_SHORT_TASK) {
- return cy.get(`${contextSelector} clr-datagrid[data-automation=clr-grid-loaded]`, { timeout: this.resolveTimeout(timeout) }).should('exist');
- }
-
- /**
- * ** Returns current browser Url.
- *
- * @param {number} timeout
- * @returns {Cypress.Chainable}
- */
- getCurrentUrl(timeout) {
- return BasePagePO.getCurrentUrl(timeout);
- }
-
- /**
- * ** Returns current browser Url normalized.
- *
- * @param {{includeUrl?: boolean; includeBaseUrl?: boolean; includePathSegment?: boolean; includeQueryString?: boolean; decodeQueryString?: boolean;}} extras
- * @returns {Cypress.Chainable<{pathSegment: string; queryParams: {[key: string]: string}; baseUrl?: string; url?: string}>}
- */
- getCurrentUrlNormalized(extras = { includeQueryString: true }) {
- return this.getCurrentUrl().then((locationHref) => {
- const fullUrlSplit = locationHref.split('?');
- const url = fullUrlSplit[0];
- const queryString = fullUrlSplit[1] ?? '';
- const pathSegment = url.replace(Cypress.config().baseUrl, '');
-
- /**
- * @type {{pathSegment: string; queryParams: {[key: string]: string}; baseUrl?: string; url?: string}}
- */
- const normalizedData = {};
-
- if (extras.includeBaseUrl) {
- normalizedData.baseUrl = Cypress.config().baseUrl;
- }
-
- if (extras.includeUrl) {
- normalizedData.url = url;
- }
-
- if (extras.includePathSegment) {
- normalizedData.pathSegment = `/${pathSegment.replace(/^\/+/, '')}`;
- }
-
- if (extras.includeQueryString) {
- normalizedData.queryParams = queryString
- .split('&')
- .map((queryStringChunk) => {
- if (queryStringChunk.length === 0) {
- return {};
- }
-
- const splitParam = queryStringChunk.split('=');
-
- return {
- [splitParam[0]]: extras.decodeQueryString ? decodeURIComponent(splitParam[1]) : splitParam[1]
- };
- })
- .reduce((accumulator, currentValue) => {
- return {
- ...accumulator,
- ...currentValue
- };
- }, {});
- }
-
- return cy.wrap(normalizedData);
- });
- }
-
- // Selectors
-
- /**
- * ** Get Page Title.
- *
- * @param {number | undefined | null} timeout
- * @returns {Cypress.Chainable>}
- */
- getPageTitle(timeout) {
- return cy.get('[data-cy=data-pipelines-page-title]', {
- timeout: this.resolveTimeout(timeout ?? 30000)
- });
- }
-
- /**
- * ** Get side menu nav group btn for Explore
- *
- * @returns {Cypress.Chainable>}
- */
- getSideMenuExploreGroupBtn() {
- return cy.get('[data-cy=data-pipelines-nav-group-explore] button').should('exist').contains('Explore');
- }
-
- /**
- * ** Get side menu nav group btn for Manage
- *
- * @returns {Cypress.Chainable>}
- */
- getSideMenuManageGroupBtn() {
- return cy.get('[data-cy=data-pipelines-nav-group-manage] button').should('exist').contains('Manage');
- }
-
- /**
- * ** Get side menu navigation link with given id.
- *
- * @param {string} navLinkId
- * @returns {Cypress.Chainable>}
- */
- getSideMenuNavLink(navLinkId) {
- return cy.get(`#${navLinkId} > span`);
- }
-
- /**
- * ** Get toast element.
- *
- * @param {number | undefined | null} timeout
- * @returns {Cypress.Chainable>}
- */
- getToast(timeout) {
- return cy.get('vdk-toast-container vdk-toast', {
- timeout: this.resolveTimeout(timeout)
- });
- }
-
- /**
- * ** Get Toast title.
- *
- * @param {number | undefined | null} timeout
- * @returns {Cypress.Chainable>}
- */
- getToastTitle(timeout) {
- return this.getToast(timeout).get('.toast-title');
- }
-
- /**
- * ** Get Toast dismiss button.
- *
- * @param {number | undefined | null} timeout
- * @returns {Cypress.Chainable>}
- */
- getToastDismiss(timeout) {
- return this.getToast(timeout).get('.dismiss-bg');
- }
-
- /**
- * ** Get Modal dialog.
- *
- * @param {number | undefined | null} timeout
- * @returns {Cypress.Chainable>}
- */
- getModal(timeout) {
- return cy.get('clr-modal .modal-dialog', {
- timeout: this.resolveTimeout(timeout)
- });
- }
-
- /**
- * ** Get DataGrid.
- *
- * - Override to select desired DataGrid.
- *
- * @param {string|null} contextSelector
- * @returns {Cypress.Chainable>}
- */
- getGrid(contextSelector = null) {
- if (contextSelector) {
- return cy.get(`${contextSelector} clr-datagrid`);
- }
-
- return cy.get('clr-datagrid');
- }
-
- /**
- * ** Get Cell from DataGrid using the searchQuery.
- *
- * @param {string} searchQuery
- * @returns {Cypress.Chainable>}
- */
- getGridCell(searchQuery) {
- return this.getGrid().contains('clr-dg-cell', searchQuery);
- }
-
- /**
- * ** Get Row from DataGrid using the searchQuery that identifies one of the Cells.
- *
- * @param {string} searchQuery
- * @returns {Cypress.Chainable>}
- */
- getGridRow(searchQuery) {
- return this.getGridCell(searchQuery).parents('clr-dg-row');
- }
-
- /**
- * ** Get all Rows from DatGrid.
- *
- * @returns {Cypress.Chainable>}
- */
- getGridRows() {
- return this.getGrid().find('clr-dg-row');
- }
-
- /**
- * ** Get select button from Row that is identified by the searchQuery.
- *
- * @param {string} searchQuery
- * @returns {Cypress.Chainable>}
- */
- getGridRowSelectBtn(searchQuery) {
- return this.getGridRow(searchQuery).find('.datagrid-select input');
- }
-
- // Actions
-
- /**
- * ** Open Explore side menu nav group.
- *
- * @return {Cypress.Chainable}
- */
- openSideMenuNavExplore() {
- return this.getSideMenuExploreGroupBtn()
- .should('exist')
- .scrollIntoView()
- .click({ force: true })
- .then(() => this.waitForViewToRenderShort());
- }
-
- /**
- * ** Open Manage side menu nav group.
- *
- * @return {Cypress.Chainable}
- */
- openSideMenuNavManage() {
- return this.getSideMenuManageGroupBtn()
- .should('exist')
- .scrollIntoView()
- .click({ force: true })
- .then(() => this.waitForViewToRenderShort());
- }
-
- /**
- * ** Navigate to Manage page through link with provided id.
- *
- * @param {string} navLinkId
- * @returns {Cypress.Chainable}
- */
- navigateToPage(navLinkId) {
- return this.getSideMenuNavLink(navLinkId).should('exist').click({ force: true });
- }
-
- /**
- * ** Resolve timeout using provided value or fallback to default value.
- *
- * @param {number | undefined | null} timeout
- * @returns {number}
- */
- resolveTimeout(timeout) {
- return timeout === undefined ? Cypress.config('defaultCommandTimeout') : timeout;
- }
-
- /**
- * ** Read file with provided name in provided directory.
- *
- * @param {string} folderName
- * @param {string} fileName
- * @returns {Cypress.Chainable}
- */
- readFile(folderName, fileName) {
- const downloadsFolder = Cypress.config(folderName);
-
- return cy.readFile(path.join(downloadsFolder, fileName));
- }
-
- /**
- * ** Clear local storage key if provided, otherwise clear everything.
- *
- * @param {string | undefined | null} key
- */
- clearLocalStorage(key) {
- if (key) {
- cy.clearLocalStorage(key);
-
- return;
- }
-
- cy.clearLocalStorage();
- }
-
- selectGridRow(searchQuery) {
- this.getGridRowSelectBtn(searchQuery).should('exist').scrollIntoView().check({ force: true });
-
- this.waitForActionThinkingTime();
- }
-
- /**
- * ** Wait until Data grid is loaded.
- *
- * @param {'explore'|'manage'} contextSelector
- * @param {number} timeout
- * @returns {Cypress.Chainable}
- */
- _waitForGridToLoad(contextSelector, timeout = DataJobsBasePO.WAIT_SHORT_TASK) {
- return cy.get(`[data-cy=${contextSelector}] clr-datagrid[data-automation=clr-grid-loaded]`, { timeout: this.resolveTimeout(timeout) }).should('exist');
- }
+ const splitParam = queryStringChunk.split("=");
+
+ return {
+ [splitParam[0]]: extras.decodeQueryString
+ ? decodeURIComponent(splitParam[1])
+ : splitParam[1],
+ };
+ })
+ .reduce((accumulator, currentValue) => {
+ return {
+ ...accumulator,
+ ...currentValue,
+ };
+ }, {});
+ }
+
+ return cy.wrap(normalizedData);
+ });
+ }
+
+ // Selectors
+
+ /**
+ * ** Get Page Title.
+ *
+ * @param {number | undefined | null} timeout
+ * @returns {Cypress.Chainable>}
+ */
+ getPageTitle(timeout) {
+ return cy.get("[data-cy=data-pipelines-page-title]", {
+ timeout: this.resolveTimeout(timeout ?? 30000),
+ });
+ }
+
+ /**
+ * ** Get side menu nav group btn for Explore
+ *
+ * @returns {Cypress.Chainable>}
+ */
+ getSideMenuExploreGroupBtn() {
+ return cy
+ .get("[data-cy=data-pipelines-nav-group-explore] button")
+ .should("exist")
+ .contains("Explore");
+ }
+
+ /**
+ * ** Get side menu nav group btn for Manage
+ *
+ * @returns {Cypress.Chainable>}
+ */
+ getSideMenuManageGroupBtn() {
+ return cy
+ .get("[data-cy=data-pipelines-nav-group-manage] button")
+ .should("exist")
+ .contains("Manage");
+ }
+
+ /**
+ * ** Get side menu navigation link with given id.
+ *
+ * @param {string} navLinkId
+ * @returns {Cypress.Chainable>}
+ */
+ getSideMenuNavLink(navLinkId) {
+ return cy.get(`#${navLinkId} > span`);
+ }
+
+ /**
+ * ** Get toast element.
+ *
+ * @param {number | undefined | null} timeout
+ * @returns {Cypress.Chainable>}
+ */
+ getToast(timeout) {
+ return cy.get("vdk-toast-container vdk-toast", {
+ timeout: this.resolveTimeout(timeout),
+ });
+ }
+
+ /**
+ * ** Get Toast title.
+ *
+ * @param {number | undefined | null} timeout
+ * @returns {Cypress.Chainable>}
+ */
+ getToastTitle(timeout) {
+ return this.getToast(timeout).get(".toast-title");
+ }
+
+ /**
+ * ** Get Toast dismiss button.
+ *
+ * @param {number | undefined | null} timeout
+ * @returns {Cypress.Chainable>}
+ */
+ getToastDismiss(timeout) {
+ return this.getToast(timeout).get(".dismiss-bg");
+ }
+
+ /**
+ * ** Get Modal dialog.
+ *
+ * @param {number | undefined | null} timeout
+ * @returns {Cypress.Chainable>}
+ */
+ getModal(timeout) {
+ return cy.get("clr-modal .modal-dialog", {
+ timeout: this.resolveTimeout(timeout),
+ });
+ }
+
+ /**
+ * ** Get DataGrid.
+ *
+ * - Override to select desired DataGrid.
+ *
+ * @param {string|null} contextSelector
+ * @returns {Cypress.Chainable>}
+ */
+ getGrid(contextSelector = null) {
+ if (contextSelector) {
+ return cy.get(`${contextSelector} clr-datagrid`);
+ }
+
+ return cy.get("clr-datagrid");
+ }
+
+ /**
+ * ** Get Cell from DataGrid using the searchQuery.
+ *
+ * @param {string} searchQuery
+ * @returns {Cypress.Chainable>}
+ */
+ getGridCell(searchQuery) {
+ return this.getGrid().contains("clr-dg-cell", searchQuery);
+ }
+
+ /**
+ * ** Get Row from DataGrid using the searchQuery that identifies one of the Cells.
+ *
+ * @param {string} searchQuery
+ * @returns {Cypress.Chainable>}
+ */
+ getGridRow(searchQuery) {
+ return this.getGridCell(searchQuery).parents("clr-dg-row");
+ }
+
+ /**
+ * ** Get all Rows from DatGrid.
+ *
+ * @returns {Cypress.Chainable>}
+ */
+ getGridRows() {
+ return this.getGrid().find("clr-dg-row");
+ }
+
+ /**
+ * ** Get select button from Row that is identified by the searchQuery.
+ *
+ * @param {string} searchQuery
+ * @returns {Cypress.Chainable>}
+ */
+ getGridRowSelectBtn(searchQuery) {
+ return this.getGridRow(searchQuery).find(".datagrid-select input");
+ }
+
+ // Actions
+
+ /**
+ * ** Open Explore side menu nav group.
+ *
+ * @return {Cypress.Chainable}
+ */
+ openSideMenuNavExplore() {
+ return this.getSideMenuExploreGroupBtn()
+ .should("exist")
+ .scrollIntoView()
+ .click({ force: true })
+ .then(() => this.waitForViewToRenderShort());
+ }
+
+ /**
+ * ** Open Manage side menu nav group.
+ *
+ * @return {Cypress.Chainable}
+ */
+ openSideMenuNavManage() {
+ return this.getSideMenuManageGroupBtn()
+ .should("exist")
+ .scrollIntoView()
+ .click({ force: true })
+ .then(() => this.waitForViewToRenderShort());
+ }
+
+ /**
+ * ** Navigate to Manage page through link with provided id.
+ *
+ * @param {string} navLinkId
+ * @returns {Cypress.Chainable}
+ */
+ navigateToPage(navLinkId) {
+ return this.getSideMenuNavLink(navLinkId)
+ .should("exist")
+ .click({ force: true });
+ }
+
+ /**
+ * ** Resolve timeout using provided value or fallback to default value.
+ *
+ * @param {number | undefined | null} timeout
+ * @returns {number}
+ */
+ resolveTimeout(timeout) {
+ return timeout === undefined
+ ? Cypress.config("defaultCommandTimeout")
+ : timeout;
+ }
+
+ /**
+ * ** Read file with provided name in provided directory.
+ *
+ * @param {string} folderName
+ * @param {string} fileName
+ * @returns {Cypress.Chainable}
+ */
+ readFile(folderName, fileName) {
+ const downloadsFolder = Cypress.config(folderName);
+
+ return cy.readFile(path.join(downloadsFolder, fileName));
+ }
+
+ /**
+ * ** Clear local storage key if provided, otherwise clear everything.
+ *
+ * @param {string | undefined | null} key
+ */
+ clearLocalStorage(key) {
+ if (key) {
+ cy.clearLocalStorage(key);
+
+ return;
+ }
+
+ cy.clearLocalStorage();
+ }
+
+ selectGridRow(searchQuery) {
+ this.getGridRowSelectBtn(searchQuery)
+ .should("exist")
+ .scrollIntoView()
+ .check({ force: true });
+
+ this.waitForActionThinkingTime();
+ }
+
+ /**
+ * ** Wait until Data grid is loaded.
+ *
+ * @param {'explore'|'manage'} contextSelector
+ * @param {number} timeout
+ * @returns {Cypress.Chainable}
+ */
+ _waitForGridToLoad(
+ contextSelector,
+ timeout = DataJobsBasePO.WAIT_SHORT_TASK,
+ ) {
+ return cy
+ .get(
+ `[data-cy=${contextSelector}] clr-datagrid[data-automation=clr-grid-loaded]`,
+ { timeout: this.resolveTimeout(timeout) },
+ )
+ .should("exist");
+ }
}
diff --git a/projects/frontend/data-pipelines/gui/e2e/support/pages/base/data-pipelines/data-job-base.po.js b/projects/frontend/data-pipelines/gui/e2e/support/pages/base/data-pipelines/data-job-base.po.js
index 7121cef42c..eb37ab4ac1 100644
--- a/projects/frontend/data-pipelines/gui/e2e/support/pages/base/data-pipelines/data-job-base.po.js
+++ b/projects/frontend/data-pipelines/gui/e2e/support/pages/base/data-pipelines/data-job-base.po.js
@@ -5,401 +5,474 @@
///
-import { DataPipelinesBasePO } from './data-pipelines-base.po';
+import { DataPipelinesBasePO } from "./data-pipelines-base.po";
export class DataJobBasePO extends DataPipelinesBasePO {
- /**
- * ** Returns instance of the page object.
- *
- * @returns {DataJobBasePO}
- */
- static getPage() {
- return new DataJobBasePO();
- }
-
- /**
- * ** Init Http requests interceptors.
- */
- static initInterceptors() {
- super.initInterceptors();
-
- this.executeCypressCommand('initDataJobsSingleExecutionGetReqInterceptor');
- this.executeCypressCommand('initDataJobsExecutionsGetReqInterceptor');
- this.executeCypressCommand('initDataJobPutReqInterceptor');
- this.executeCypressCommand('initDataJobDeleteReqInterceptor');
- this.executeCypressCommand('initDataJobExecutionDeleteReqInterceptor');
- }
-
- /**
- * ** Navigate to Data Job Url.
- *
- * @param {'explore'|'manage'} context
- * @param {string} teamName
- * @param {string} jobName
- * @param {'details'|'executions'|'lineage'} subpage
- */
- static navigateTo(context, teamName, jobName, subpage) {
- const numberOfDataJobsApiGetReqInterceptorWaiting = subpage === 'details' ? 4 : 3;
-
- return this.navigateToDataJobUrl(`/${context}/data-jobs/${teamName}/${jobName}/${subpage}`, numberOfDataJobsApiGetReqInterceptorWaiting);
- }
-
- /**
- * ** Wait for Data Job put req.
- *
- * @return {Cypress.Chainable}
- */
- static waitForDataJobPutReqInterceptor() {
- return this.executeCypressCommand('waitForDataJobPutReqInterceptor', 1, 1000);
- }
-
- /**
- * ** Wait for Data Job delete req.
- *
- * @return {Cypress.Chainable}
- */
- static waitForDataJobDeleteReqInterceptor() {
- return this.executeCypressCommand('waitForDataJobDeleteReqInterceptor', 1, 1000);
- }
-
- /**
- * ** Wait for Data Job execution delete req.
- *
- * @return {Cypress.Chainable}
- */
- static waitForDataJobExecutionDeleteReqInterceptor() {
- return this.executeCypressCommand('waitForDataJobExecutionDeleteReqInterceptor', 1, 1000);
- }
-
- /**
- * ** Wait for Data Job executions get req.
- *
- * @return {Cypress.Chainable}
- */
- static waitForGetExecutionsReqInterceptor() {
- return cy.wait('@dataJobsExecutionsGetReq');
- }
-
- /**
- * ** Wait for Data Job to not have running executions.
- *
- * @return {Cypress.Chainable}
- */
- static waitForDataJobToNotHaveRunningExecution() {
- cy.log('Looking if there is ongoing running execution');
-
- let isRunningExecution = false;
-
- return cy.waitForInterceptorWithRetry('@dataJobsExecutionsGetReq', 5, {
- predicate: (interception) => {
- if (interception?.response?.statusCode !== 200) {
- return false;
- }
-
- const body = interception?.response?.body;
- if (body && body.data && body.data.content) {
- if (body.data.content.length === 0 || body.data.content[0].__typename !== 'DataJobExecution') {
- return false;
- }
-
- isRunningExecution =
- body.data.content.findIndex((e) => {
- if (!e || e.status === undefined) {
- return false;
- }
-
- return e.status?.toLowerCase() === 'running' || e.status?.toLowerCase() === 'submitted';
- }) !== -1;
-
- return true;
- }
+ /**
+ * ** Returns instance of the page object.
+ *
+ * @returns {DataJobBasePO}
+ */
+ static getPage() {
+ return new DataJobBasePO();
+ }
+
+ /**
+ * ** Init Http requests interceptors.
+ */
+ static initInterceptors() {
+ super.initInterceptors();
+
+ this.executeCypressCommand("initDataJobsSingleExecutionGetReqInterceptor");
+ this.executeCypressCommand("initDataJobsExecutionsGetReqInterceptor");
+ this.executeCypressCommand("initDataJobPutReqInterceptor");
+ this.executeCypressCommand("initDataJobDeleteReqInterceptor");
+ this.executeCypressCommand("initDataJobExecutionDeleteReqInterceptor");
+ }
+
+ /**
+ * ** Navigate to Data Job Url.
+ *
+ * @param {'explore'|'manage'} context
+ * @param {string} teamName
+ * @param {string} jobName
+ * @param {'details'|'executions'|'lineage'} subpage
+ */
+ static navigateTo(context, teamName, jobName, subpage) {
+ const numberOfDataJobsApiGetReqInterceptorWaiting =
+ subpage === "details" ? 4 : 3;
+
+ return this.navigateToDataJobUrl(
+ `/${context}/data-jobs/${teamName}/${jobName}/${subpage}`,
+ numberOfDataJobsApiGetReqInterceptorWaiting,
+ );
+ }
+
+ /**
+ * ** Wait for Data Job put req.
+ *
+ * @return {Cypress.Chainable}
+ */
+ static waitForDataJobPutReqInterceptor() {
+ return this.executeCypressCommand(
+ "waitForDataJobPutReqInterceptor",
+ 1,
+ 1000,
+ );
+ }
+
+ /**
+ * ** Wait for Data Job delete req.
+ *
+ * @return {Cypress.Chainable}
+ */
+ static waitForDataJobDeleteReqInterceptor() {
+ return this.executeCypressCommand(
+ "waitForDataJobDeleteReqInterceptor",
+ 1,
+ 1000,
+ );
+ }
+
+ /**
+ * ** Wait for Data Job execution delete req.
+ *
+ * @return {Cypress.Chainable}
+ */
+ static waitForDataJobExecutionDeleteReqInterceptor() {
+ return this.executeCypressCommand(
+ "waitForDataJobExecutionDeleteReqInterceptor",
+ 1,
+ 1000,
+ );
+ }
+
+ /**
+ * ** Wait for Data Job executions get req.
+ *
+ * @return {Cypress.Chainable}
+ */
+ static waitForGetExecutionsReqInterceptor() {
+ return cy.wait("@dataJobsExecutionsGetReq");
+ }
+
+ /**
+ * ** Wait for Data Job to not have running executions.
+ *
+ * @return {Cypress.Chainable}
+ */
+ static waitForDataJobToNotHaveRunningExecution() {
+ cy.log("Looking if there is ongoing running execution");
+
+ let isRunningExecution = false;
+
+ return cy.waitForInterceptorWithRetry("@dataJobsExecutionsGetReq", 5, {
+ predicate: (interception) => {
+ if (interception?.response?.statusCode !== 200) {
+ return false;
+ }
+ const body = interception?.response?.body;
+ if (body && body.data && body.data.content) {
+ if (
+ body.data.content.length === 0 ||
+ body.data.content[0].__typename !== "DataJobExecution"
+ ) {
+ return false;
+ }
+
+ isRunningExecution =
+ body.data.content.findIndex((e) => {
+ if (!e || e.status === undefined) {
return false;
- },
- onfulfill: () => {
- cy.log('Waiting for already running execution to stop');
-
- if (isRunningExecution) {
- DataJobBasePO.waitForDataJobToFinishExecution();
- }
- }
- });
- }
+ }
- /**
- * ** Wait for Data Job to finish execution.
- *
- * @return {Cypress.Chainable}
- */
- static waitForDataJobToFinishExecution() {
- cy.log('Waiting execution to finish');
+ return (
+ e.status?.toLowerCase() === "running" ||
+ e.status?.toLowerCase() === "submitted"
+ );
+ }) !== -1;
- return cy.waitForInterceptorWithRetry('@dataJobsSingleExecutionGetReq', 20, {
- predicate: (interception) => {
- const body = interception?.response?.body;
-
- return body?.status?.toLowerCase() !== 'running' && body?.status?.toLowerCase() !== 'submitted';
- }
- });
- }
-
- /**
- * ** Wait for Data Job execution to become canceled.
- *
- * @return {Cypress.Chainable}
- */
- static waitForDataJobToCancelExecution() {
- cy.log('Waiting to cancel execution');
-
- return cy.waitForInterceptorWithRetry('@dataJobsSingleExecutionGetReq', 20, {
- predicate: (interception) => {
- return interception?.response?.body?.status?.toLowerCase() === 'cancelled';
- }
- });
- }
-
- /**
- * ** Wait for response where there would be execution record with status SUBMITTED or RUNNING.
- *
- * @return {Cypress.Chainable}
- */
- static waitForDataJobStartExecute() {
- cy.log('Waiting execution to start SUBMITTED|RUNNING');
-
- return cy.waitForInterceptorWithRetry('@dataJobsExecutionsGetReq', 20, {
- predicate: (interception) => {
- if (interception?.response?.statusCode !== 200) {
- return false;
- }
-
- const body = interception?.response?.body;
- if (body?.data?.content?.length === 0 || body?.data?.content[0]?.__typename !== 'DataJobExecution') {
- return false;
- }
-
- return (
- body?.data?.content?.findIndex((e) => {
- if (!e || e.status === undefined) {
- return false;
- }
-
- return e.status?.toLowerCase() === 'running' || e.status?.toLowerCase() === 'submitted';
- }) !== -1
- );
- }
- });
- }
-
- /**
- * ** Wait for response where there would be execution record with status SUBMITTED or RUNNING.
- *
- * @return {Cypress.Chainable}
- */
- static waitForPollingToShowRunningExecution() {
- cy.log('Waiting for pooling execution with status RUNNING');
-
- return cy.waitForInterceptorWithRetry('@dataJobsSingleExecutionGetReq', 10, {
- predicate: (interception) => {
- const body = interception?.response?.body;
- const status = `${body?.status}`.toLowerCase();
-
- if (status === 'running') {
- return true;
- } else {
- if (status !== 'submitted') {
- cy.log(`Execution status never changed to RUNNING, current is ${status.toUpperCase()}`);
-
- return true;
- }
-
- return false;
- }
- }
- });
- }
-
- /**
- * ** Wait for Data Job put req.
- *
- * @return {Cypress.Chainable}
- */
- waitForDataJobPutReqInterceptor() {
- return DataJobBasePO.waitForDataJobPutReqInterceptor();
- }
-
- /**
- * ** Wait for Data Job delete req.
- *
- * @return {Cypress.Chainable}
- */
- waitForDataJobDeleteReqInterceptor() {
- return DataJobBasePO.waitForDataJobDeleteReqInterceptor();
- }
-
- /**
- * ** Wait for Data Job execution delete req.
- *
- * @return {Cypress.Chainable}
- */
- waitForDataJobExecutionDeleteReqInterceptor() {
- return DataJobBasePO.waitForDataJobExecutionDeleteReqInterceptor();
- }
-
- /**
- * ** Wait for Data Job executions get req.
- *
- * @return {Cypress.Chainable}
- */
- waitForGetExecutionsReqInterceptor() {
- const waitChainable = DataJobBasePO.waitForGetExecutionsReqInterceptor();
- if (waitChainable) {
- return waitChainable;
+ return true;
}
- return cy.wait(500).then(() => this.waitForGetExecutionsReqInterceptor());
- }
-
- /* Selectors */
-
- getNavigateBackBtn() {
- return cy.get('[data-cy=data-pipelines-job-navigate-back]');
- }
+ return false;
+ },
+ onfulfill: () => {
+ cy.log("Waiting for already running execution to stop");
- getExecuteNowButton() {
- return cy.get('[data-cy=data-pipelines-job-execute-btn]', {
- timeout: DataJobBasePO.WAIT_SHORT_TASK
- });
- }
-
- getCancelExecutionButton() {
- return cy.get('[data-cy=data-pipelines-job-cancel-execution-btn]');
- }
-
- getExecuteOrCancelButton() {
- return cy.get('[data-cy=data-pipelines-job-actions-container]').then(($container) => {
- if ($container && $container.length > 0) {
- const $btn = $container.find('[data-cy=data-pipelines-job-execute-btn]');
-
- if ($btn && $btn.length > 0) {
- return $btn;
- }
- }
-
- return $container.find('[data-cy=data-pipelines-job-cancel-execution-btn]');
- });
- }
-
- getConfirmDialogButton() {
- return cy.get('[data-cy="confirmation-dialog-ok-btn"]');
- }
-
- getActionDropdownBtn() {
- return cy.get('[data-cy=data-pipelines-job-action-dropdown-btn]');
- }
-
- getDownloadKeyBtn() {
- return cy.get('[data-cy=data-pipelines-job-download-btn]');
- }
-
- getDeleteJobBtn() {
- return cy.get('[data-cy=data-pipelines-job-delete-btn]');
- }
-
- getConfirmDeleteBtn() {
- return cy.get('#removeBtn');
- }
-
- getDetailsTab() {
- return cy.get('[data-cy=data-pipelines-job-details-tab]');
- }
-
- getExecutionsTab() {
- return cy.get('[data-cy=data-pipelines-job-executions-tab]');
- }
-
- getExecutionStatus() {
- return cy.get('[data-cy="data-pipelines-job-execution-status"]');
- }
-
- /* Actions */
-
- executeNow(waitToStartExecution = false) {
- this.getExecuteNowButton().should('exist').scrollIntoView().click({ force: true });
-
- this.confirmInConfirmDialog(() => {
- this.waitForDataJobExecutionPostReqInterceptor();
- });
-
- if (waitToStartExecution) {
- DataJobBasePO.waitForDataJobStartExecute();
- DataJobBasePO.waitForPollingToShowRunningExecution();
- this.waitForViewToRenderShort();
+ if (isRunningExecution) {
+ DataJobBasePO.waitForDataJobToFinishExecution();
}
- }
-
- cancelExecution(waitExecutionToStop = false) {
- this.getCancelExecutionButton().should('exist').scrollIntoView().click({ force: true });
-
- this.confirmInConfirmDialog(() => {
- this.waitForDataJobExecutionDeleteReqInterceptor();
- });
-
- if (waitExecutionToStop) {
- DataJobBasePO.waitForDataJobToCancelExecution();
- this.waitForViewToRenderShort();
+ },
+ });
+ }
+
+ /**
+ * ** Wait for Data Job to finish execution.
+ *
+ * @return {Cypress.Chainable}
+ */
+ static waitForDataJobToFinishExecution() {
+ cy.log("Waiting execution to finish");
+
+ return cy.waitForInterceptorWithRetry(
+ "@dataJobsSingleExecutionGetReq",
+ 20,
+ {
+ predicate: (interception) => {
+ const body = interception?.response?.body;
+
+ return (
+ body?.status?.toLowerCase() !== "running" &&
+ body?.status?.toLowerCase() !== "submitted"
+ );
+ },
+ },
+ );
+ }
+
+ /**
+ * ** Wait for Data Job execution to become canceled.
+ *
+ * @return {Cypress.Chainable}
+ */
+ static waitForDataJobToCancelExecution() {
+ cy.log("Waiting to cancel execution");
+
+ return cy.waitForInterceptorWithRetry(
+ "@dataJobsSingleExecutionGetReq",
+ 20,
+ {
+ predicate: (interception) => {
+ return (
+ interception?.response?.body?.status?.toLowerCase() === "cancelled"
+ );
+ },
+ },
+ );
+ }
+
+ /**
+ * ** Wait for response where there would be execution record with status SUBMITTED or RUNNING.
+ *
+ * @return {Cypress.Chainable}
+ */
+ static waitForDataJobStartExecute() {
+ cy.log("Waiting execution to start SUBMITTED|RUNNING");
+
+ return cy.waitForInterceptorWithRetry("@dataJobsExecutionsGetReq", 20, {
+ predicate: (interception) => {
+ if (interception?.response?.statusCode !== 200) {
+ return false;
}
- }
-
- openActionDropdown() {
- this.getActionDropdownBtn().should('exist').scrollIntoView().should('be.visible').click({ force: true });
- this.waitForViewToRenderShort();
- }
+ const body = interception?.response?.body;
+ if (
+ body?.data?.content?.length === 0 ||
+ body?.data?.content[0]?.__typename !== "DataJobExecution"
+ ) {
+ return false;
+ }
- downloadJobKey() {
- this.getDownloadKeyBtn().should('exist').scrollIntoView().should('be.visible').click({ force: true });
+ return (
+ body?.data?.content?.findIndex((e) => {
+ if (!e || e.status === undefined) {
+ return false;
+ }
- this.waitForDataJobsApiGetReqInterceptor();
- }
+ return (
+ e.status?.toLowerCase() === "running" ||
+ e.status?.toLowerCase() === "submitted"
+ );
+ }) !== -1
+ );
+ },
+ });
+ }
+
+ /**
+ * ** Wait for response where there would be execution record with status SUBMITTED or RUNNING.
+ *
+ * @return {Cypress.Chainable}
+ */
+ static waitForPollingToShowRunningExecution() {
+ cy.log("Waiting for pooling execution with status RUNNING");
+
+ return cy.waitForInterceptorWithRetry(
+ "@dataJobsSingleExecutionGetReq",
+ 10,
+ {
+ predicate: (interception) => {
+ const body = interception?.response?.body;
+ const status = `${body?.status}`.toLowerCase();
+
+ if (status === "running") {
+ return true;
+ } else {
+ if (status !== "submitted") {
+ cy.log(
+ `Execution status never changed to RUNNING, current is ${status.toUpperCase()}`,
+ );
+
+ return true;
+ }
- deleteJob() {
- this.getDeleteJobBtn().scrollIntoView().should('be.visible').click({ force: true });
+ return false;
+ }
+ },
+ },
+ );
+ }
+
+ /**
+ * ** Wait for Data Job put req.
+ *
+ * @return {Cypress.Chainable}
+ */
+ waitForDataJobPutReqInterceptor() {
+ return DataJobBasePO.waitForDataJobPutReqInterceptor();
+ }
+
+ /**
+ * ** Wait for Data Job delete req.
+ *
+ * @return {Cypress.Chainable}
+ */
+ waitForDataJobDeleteReqInterceptor() {
+ return DataJobBasePO.waitForDataJobDeleteReqInterceptor();
+ }
+
+ /**
+ * ** Wait for Data Job execution delete req.
+ *
+ * @return {Cypress.Chainable}
+ */
+ waitForDataJobExecutionDeleteReqInterceptor() {
+ return DataJobBasePO.waitForDataJobExecutionDeleteReqInterceptor();
+ }
+
+ /**
+ * ** Wait for Data Job executions get req.
+ *
+ * @return {Cypress.Chainable}
+ */
+ waitForGetExecutionsReqInterceptor() {
+ const waitChainable = DataJobBasePO.waitForGetExecutionsReqInterceptor();
+ if (waitChainable) {
+ return waitChainable;
+ }
+
+ return cy.wait(500).then(() => this.waitForGetExecutionsReqInterceptor());
+ }
+
+ /* Selectors */
+
+ getNavigateBackBtn() {
+ return cy.get("[data-cy=data-pipelines-job-navigate-back]");
+ }
+
+ getExecuteNowButton() {
+ return cy.get("[data-cy=data-pipelines-job-execute-btn]", {
+ timeout: DataJobBasePO.WAIT_SHORT_TASK,
+ });
+ }
+
+ getCancelExecutionButton() {
+ return cy.get("[data-cy=data-pipelines-job-cancel-execution-btn]");
+ }
+
+ getExecuteOrCancelButton() {
+ return cy
+ .get("[data-cy=data-pipelines-job-actions-container]")
+ .then(($container) => {
+ if ($container && $container.length > 0) {
+ const $btn = $container.find(
+ "[data-cy=data-pipelines-job-execute-btn]",
+ );
+
+ if ($btn && $btn.length > 0) {
+ return $btn;
+ }
+ }
- this.waitForViewToRenderShort();
+ return $container.find(
+ "[data-cy=data-pipelines-job-cancel-execution-btn]",
+ );
+ });
+ }
- this.confirmDeleteJob(() => {
- this.waitForDataJobDeleteReqInterceptor();
- });
- }
+ getConfirmDialogButton() {
+ return cy.get('[data-cy="confirmation-dialog-ok-btn"]');
+ }
+
+ getActionDropdownBtn() {
+ return cy.get("[data-cy=data-pipelines-job-action-dropdown-btn]");
+ }
+
+ getDownloadKeyBtn() {
+ return cy.get("[data-cy=data-pipelines-job-download-btn]");
+ }
+
+ getDeleteJobBtn() {
+ return cy.get("[data-cy=data-pipelines-job-delete-btn]");
+ }
+
+ getConfirmDeleteBtn() {
+ return cy.get("#removeBtn");
+ }
+
+ getDetailsTab() {
+ return cy.get("[data-cy=data-pipelines-job-details-tab]");
+ }
+
+ getExecutionsTab() {
+ return cy.get("[data-cy=data-pipelines-job-executions-tab]");
+ }
- /**
- * ** Confirm Job deletion.
- *
- * @param {() => void} interceptor
- */
- confirmDeleteJob(interceptor) {
- this.getConfirmDeleteBtn().scrollIntoView().should('be.visible').click({ force: true });
+ getExecutionStatus() {
+ return cy.get('[data-cy="data-pipelines-job-execution-status"]');
+ }
- if (interceptor) {
- interceptor();
- }
- }
+ /* Actions */
+
+ executeNow(waitToStartExecution = false) {
+ this.getExecuteNowButton()
+ .should("exist")
+ .scrollIntoView()
+ .click({ force: true });
+
+ this.confirmInConfirmDialog(() => {
+ this.waitForDataJobExecutionPostReqInterceptor();
+ });
+
+ if (waitToStartExecution) {
+ DataJobBasePO.waitForDataJobStartExecute();
+ DataJobBasePO.waitForPollingToShowRunningExecution();
+ this.waitForViewToRenderShort();
+ }
+ }
+
+ cancelExecution(waitExecutionToStop = false) {
+ this.getCancelExecutionButton()
+ .should("exist")
+ .scrollIntoView()
+ .click({ force: true });
+
+ this.confirmInConfirmDialog(() => {
+ this.waitForDataJobExecutionDeleteReqInterceptor();
+ });
+
+ if (waitExecutionToStop) {
+ DataJobBasePO.waitForDataJobToCancelExecution();
+ this.waitForViewToRenderShort();
+ }
+ }
+
+ openActionDropdown() {
+ this.getActionDropdownBtn()
+ .should("exist")
+ .scrollIntoView()
+ .should("be.visible")
+ .click({ force: true });
+
+ this.waitForViewToRenderShort();
+ }
+
+ downloadJobKey() {
+ this.getDownloadKeyBtn()
+ .should("exist")
+ .scrollIntoView()
+ .should("be.visible")
+ .click({ force: true });
+
+ this.waitForDataJobsApiGetReqInterceptor();
+ }
+
+ deleteJob() {
+ this.getDeleteJobBtn()
+ .scrollIntoView()
+ .should("be.visible")
+ .click({ force: true });
+
+ this.waitForViewToRenderShort();
+
+ this.confirmDeleteJob(() => {
+ this.waitForDataJobDeleteReqInterceptor();
+ });
+ }
- navigateBackToDataJobs() {
- this.getNavigateBackBtn().should('be.visible').click({ force: true });
+ /**
+ * ** Confirm Job deletion.
+ *
+ * @param {() => void} interceptor
+ */
+ confirmDeleteJob(interceptor) {
+ this.getConfirmDeleteBtn()
+ .scrollIntoView()
+ .should("be.visible")
+ .click({ force: true });
- this.waitForGridDataLoad();
- }
+ if (interceptor) {
+ interceptor();
+ }
+ }
- openDetailsTab() {
- this.getDetailsTab().should('exist').click({ force: true });
+ navigateBackToDataJobs() {
+ this.getNavigateBackBtn().should("be.visible").click({ force: true });
- this.waitForDataJobsApiGetReqInterceptor();
- }
+ this.waitForGridDataLoad();
+ }
+
+ openDetailsTab() {
+ this.getDetailsTab().should("exist").click({ force: true });
+
+ this.waitForDataJobsApiGetReqInterceptor();
+ }
- openExecutionsTab() {
- this.getExecutionsTab().should('exist').click({ force: true });
+ openExecutionsTab() {
+ this.getExecutionsTab().should("exist").click({ force: true });
- this.waitForGridDataLoad();
- }
+ this.waitForGridDataLoad();
+ }
}
diff --git a/projects/frontend/data-pipelines/gui/e2e/support/pages/base/data-pipelines/data-job-details-base.po.js b/projects/frontend/data-pipelines/gui/e2e/support/pages/base/data-pipelines/data-job-details-base.po.js
index 407a856e35..ec24e0f909 100644
--- a/projects/frontend/data-pipelines/gui/e2e/support/pages/base/data-pipelines/data-job-details-base.po.js
+++ b/projects/frontend/data-pipelines/gui/e2e/support/pages/base/data-pipelines/data-job-details-base.po.js
@@ -5,82 +5,82 @@
///
-import { DataJobBasePO } from './data-job-base.po';
+import { DataJobBasePO } from "./data-job-base.po";
export class DataJobDetailsBasePO extends DataJobBasePO {
- /**
- * ** Returns instance of the page object.
- *
- * @returns {DataJobDetailsBasePO}
- */
- static getPage() {
- return new DataJobDetailsBasePO();
- }
-
- /**
- * ** Navigate to Data Job Url.
- *
- * @param {'explore'|'manage'} context
- * @param {string} teamName
- * @param {string} jobName
- */
- static navigateTo(context, teamName, jobName) {
- return super.navigateTo(context, teamName, jobName, 'details');
- }
-
- // Selectors
-
- getStatusField() {
- return cy.get('[data-cy=data-pipelines-job-details-status]');
- }
-
- getDescriptionField() {
- return cy.get('[data-cy=data-pipelines-job-details-description]');
- }
-
- getDescriptionFull() {
- return cy.get('[data-cy=description-show-less]');
- }
-
- getShowDescriptionMoreBtn() {
- return cy.get('[data-cy=description-show-more]');
- }
-
- getTeamField() {
- return cy.get('[data-cy=data-pipelines-job-details-team]');
- }
-
- getScheduleField() {
- return cy.get('[data-cy=data-pipelines-job-details-schedule]');
- }
-
- getSourceField() {
- return cy.get('[data-cy=data-pipelines-job-details-source]');
- }
-
- getOnDeployedField() {
- return cy.get('[data-cy=data-pipelines-job-details-on-deployed]');
- }
-
- getOnPlatformErrorField() {
- 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]');
- }
-
- getOnSuccessField() {
- return cy.get('[data-cy=data-pipelines-job-details-on-success]');
- }
-
- // Actions
-
- showMoreDescription() {
- this.getShowDescriptionMoreBtn().should('exist').click({ force: true });
-
- this.waitForViewToRenderShort();
-
- return this;
- }
+ /**
+ * ** Returns instance of the page object.
+ *
+ * @returns {DataJobDetailsBasePO}
+ */
+ static getPage() {
+ return new DataJobDetailsBasePO();
+ }
+
+ /**
+ * ** Navigate to Data Job Url.
+ *
+ * @param {'explore'|'manage'} context
+ * @param {string} teamName
+ * @param {string} jobName
+ */
+ static navigateTo(context, teamName, jobName) {
+ return super.navigateTo(context, teamName, jobName, "details");
+ }
+
+ // Selectors
+
+ getStatusField() {
+ return cy.get("[data-cy=data-pipelines-job-details-status]");
+ }
+
+ getDescriptionField() {
+ return cy.get("[data-cy=data-pipelines-job-details-description]");
+ }
+
+ getDescriptionFull() {
+ return cy.get("[data-cy=description-show-less]");
+ }
+
+ getShowDescriptionMoreBtn() {
+ return cy.get("[data-cy=description-show-more]");
+ }
+
+ getTeamField() {
+ return cy.get("[data-cy=data-pipelines-job-details-team]");
+ }
+
+ getScheduleField() {
+ return cy.get("[data-cy=data-pipelines-job-details-schedule]");
+ }
+
+ getSourceField() {
+ return cy.get("[data-cy=data-pipelines-job-details-source]");
+ }
+
+ getOnDeployedField() {
+ return cy.get("[data-cy=data-pipelines-job-details-on-deployed]");
+ }
+
+ getOnPlatformErrorField() {
+ 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]");
+ }
+
+ getOnSuccessField() {
+ return cy.get("[data-cy=data-pipelines-job-details-on-success]");
+ }
+
+ // Actions
+
+ showMoreDescription() {
+ this.getShowDescriptionMoreBtn().should("exist").click({ force: true });
+
+ this.waitForViewToRenderShort();
+
+ return this;
+ }
}
diff --git a/projects/frontend/data-pipelines/gui/e2e/support/pages/base/data-pipelines/data-jobs-base.po.js b/projects/frontend/data-pipelines/gui/e2e/support/pages/base/data-pipelines/data-jobs-base.po.js
index d1e5e06f6b..2b2e1fa8de 100644
--- a/projects/frontend/data-pipelines/gui/e2e/support/pages/base/data-pipelines/data-jobs-base.po.js
+++ b/projects/frontend/data-pipelines/gui/e2e/support/pages/base/data-pipelines/data-jobs-base.po.js
@@ -5,327 +5,366 @@
///
-import { DataPipelinesBasePO } from './data-pipelines-base.po';
+import { DataPipelinesBasePO } from "./data-pipelines-base.po";
export class DataJobsBasePO extends DataPipelinesBasePO {
- /**
- * ** Returns instance of the page object.
- *
- * @returns {DataJobsBasePO}
- */
- static getPage() {
- return new DataJobsBasePO();
- }
-
- /**
- * ** Navigate to Data Job Url.
- *
- * @param {'explore'|'manage'} context
- */
- static navigateTo(context) {
- return this.navigateToDataJobUrl(`/${context}/data-jobs`);
- }
-
- /**
- * ** Navigate to Data Job Url.
- * ** Do not wait for bootstrap and interceptors
- * @param {'explore'|'manage'} context
- */
- static navigateToNoBootstrap(context) {
- return this.navigateToDataJobUrlNoBootstrap(`/${context}/data-jobs`);
- }
- // Selectors
-
- getDataGridRefreshButton() {
- throw new Error('Method should be overridden by subclasses');
- }
-
- getDataGrid() {
- return cy.get('clr-datagrid');
- }
-
- getDataGridSearchInput() {
- return cy.get('[data-test-id=search-input]').first();
- }
-
- getDataGridClearSearchButton() {
- return cy.get('[data-test-id="clear-search-btn"]').first();
- }
-
- getQuickFilters() {
- return cy.get('[data-cy=data-pipelines-quick-filters] > span');
- }
-
- getHeaderColumnJobName() {
- return cy.get('[data-cy=data-pipelines-jobs-name-column]');
- }
-
- getHeaderColumnTeamName() {
- return cy.get('[data-cy=data-pipelines-jobs-team-column]');
- }
-
- getHeaderColumnDescriptionName() {
- return cy.get('[data-cy=data-pipelines-jobs-description-column]');
- }
-
- getDataGridJobNameFilter() {
- return this.getHeaderColumnJobName().should('exist').find('clr-dg-filter button');
- }
-
- getHeaderColumnJobNameSortBtn() {
- return this.getHeaderColumnJobName().should('exist').find('.datagrid-column-title');
- }
-
- getDataGridJobTeamFilter() {
- return this.getHeaderColumnTeamName().should('exist').find('clr-dg-filter button');
- }
-
- getHeaderColumnJobTeamSortBtn() {
- return this.getHeaderColumnTeamName().should('exist').find('.datagrid-column-title');
- }
-
- getDataGridJobDescriptionFilter() {
- return this.getHeaderColumnDescriptionName().should('exist').find('clr-dg-filter button');
- }
-
- getDataGridFilterInput() {
- return cy.get('div.datagrid-filter input');
- }
-
- getDataGridHeaderCell(content) {
- return this.getDataGrid()
- .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');
- }
-
- getDataGridRowByIndex(rowIndex) {
- return this.getDataGridRows()
- .should('have.length.gte', rowIndex - 1)
- .then((rows) => Array.from(rows)[rowIndex - 1]);
- }
-
- getDataGridRowByName(jobName) {
- return this.getDataGridCell(jobName).parents('clr-dg-row');
- }
-
- getDataGridCells(rowIndex) {
- return this.getDataGridRowByIndex(rowIndex).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]);
- }
-
- getDataGridCellByIdentifier(rowIndex, identifier) {
- return this.getDataGridRowByIndex(rowIndex).should('exist').find(identifier);
- }
-
- 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)
- });
- }
-
- getDataGridStatusCells() {
- return this.getDataGrid().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]');
- }
-
- getDataGridColumnToggle() {
- return this.getDataGrid().should('exist').find('clr-dg-column-toggle button');
- }
+ /**
+ * ** Returns instance of the page object.
+ *
+ * @returns {DataJobsBasePO}
+ */
+ static getPage() {
+ return new DataJobsBasePO();
+ }
+
+ /**
+ * ** Navigate to Data Job Url.
+ *
+ * @param {'explore'|'manage'} context
+ */
+ static navigateTo(context) {
+ return this.navigateToDataJobUrl(`/${context}/data-jobs`);
+ }
+
+ /**
+ * ** Navigate to Data Job Url.
+ * ** Do not wait for bootstrap and interceptors
+ * @param {'explore'|'manage'} context
+ */
+ static navigateToNoBootstrap(context) {
+ return this.navigateToDataJobUrlNoBootstrap(`/${context}/data-jobs`);
+ }
+ // Selectors
+
+ getDataGridRefreshButton() {
+ throw new Error("Method should be overridden by subclasses");
+ }
+
+ getDataGrid() {
+ return cy.get("clr-datagrid");
+ }
+
+ getDataGridSearchInput() {
+ return cy.get("[data-test-id=search-input]").first();
+ }
+
+ getDataGridClearSearchButton() {
+ return cy.get('[data-test-id="clear-search-btn"]').first();
+ }
+
+ getQuickFilters() {
+ return cy.get("[data-cy=data-pipelines-quick-filters] > span");
+ }
+
+ getHeaderColumnJobName() {
+ return cy.get("[data-cy=data-pipelines-jobs-name-column]");
+ }
+
+ getHeaderColumnTeamName() {
+ return cy.get("[data-cy=data-pipelines-jobs-team-column]");
+ }
+
+ getHeaderColumnDescriptionName() {
+ return cy.get("[data-cy=data-pipelines-jobs-description-column]");
+ }
+
+ getDataGridJobNameFilter() {
+ return this.getHeaderColumnJobName()
+ .should("exist")
+ .find("clr-dg-filter button");
+ }
+
+ getHeaderColumnJobNameSortBtn() {
+ return this.getHeaderColumnJobName()
+ .should("exist")
+ .find(".datagrid-column-title");
+ }
+
+ getDataGridJobTeamFilter() {
+ return this.getHeaderColumnTeamName()
+ .should("exist")
+ .find("clr-dg-filter button");
+ }
+
+ getHeaderColumnJobTeamSortBtn() {
+ return this.getHeaderColumnTeamName()
+ .should("exist")
+ .find(".datagrid-column-title");
+ }
+
+ getDataGridJobDescriptionFilter() {
+ return this.getHeaderColumnDescriptionName()
+ .should("exist")
+ .find("clr-dg-filter button");
+ }
+
+ getDataGridFilterInput() {
+ return cy.get("div.datagrid-filter input");
+ }
+
+ getDataGridHeaderCell(content) {
+ return this.getDataGrid()
+ .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");
+ }
+
+ getDataGridRowByIndex(rowIndex) {
+ return this.getDataGridRows()
+ .should("have.length.gte", rowIndex - 1)
+ .then((rows) => Array.from(rows)[rowIndex - 1]);
+ }
+
+ getDataGridRowByName(jobName) {
+ return this.getDataGridCell(jobName).parents("clr-dg-row");
+ }
+
+ getDataGridCells(rowIndex) {
+ return this.getDataGridRowByIndex(rowIndex)
+ .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]);
+ }
+
+ getDataGridCellByIdentifier(rowIndex, identifier) {
+ return this.getDataGridRowByIndex(rowIndex)
+ .should("exist")
+ .find(identifier);
+ }
+
+ 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),
+ });
+ }
+
+ getDataGridStatusCells() {
+ return this.getDataGrid()
+ .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]",
+ );
+ }
+
+ getDataGridColumnToggle() {
+ return this.getDataGrid()
+ .should("exist")
+ .find("clr-dg-column-toggle button");
+ }
+
+ getDataGridNavigateBtn(team, job) {
+ throw new Error("Method should be overridden by subclasses");
+ }
+
+ getDataGridColumnShowHidePanel() {
+ return cy.get(".column-switch");
+ }
+
+ getDataGridColumnShowHideOptions() {
+ return this.getDataGridColumnShowHidePanel()
+ .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));
+ }
+
+ getDataGridColumnShowHideOption(option) {
+ return this.getDataGridColumnShowHideOptions()
+ .should("have.length.gt", 0)
+ .then((elements) =>
+ Array.from(elements).find((el) => el.innerText === option),
+ )
+ .find("input");
+ }
+
+ /**
+ * ** Get DataGrid page size selection.
+ *
+ * @returns {Cypress.Chainable>}
+ */
+ getDataGridPageSizeSelect() {
+ return this.getDataGrid().find("clr-dg-page-size .clr-page-size-select");
+ }
+
+ getDataJobPage() {
+ return cy.get("[data-cy=data-pipelines-job-page]");
+ }
+
+ // Actions
+
+ chooseQuickFilter(filterPosition) {
+ this.getQuickFilters()
+ .then((filters) => {
+ return filters && filters[filterPosition];
+ })
+ .should("exist")
+ .click({ force: true });
+
+ this.waitForGridDataLoad();
+ }
- getDataGridNavigateBtn(team, job) {
- throw new Error('Method should be overridden by subclasses');
- }
+ refreshDataGrid() {
+ this.getDataGridRefreshButton().should("exist").click({ force: true });
- getDataGridColumnShowHidePanel() {
- return cy.get('.column-switch');
- }
+ this.waitForGridDataLoad();
+ }
- getDataGridColumnShowHideOptions() {
- return this.getDataGridColumnShowHidePanel().should('exist').find('clr-checkbox-wrapper');
- }
+ /**
+ * ** Search by job name.
+ *
+ * @param {string} jobName
+ */
+ searchByJobName(jobName) {
+ this.getDataGridSearchInput().should("exist").type(jobName);
- getDataGridColumnShowHideOptionsValues() {
- return this.getDataGridColumnShowHidePanel()
- .should('exist')
- .find('clr-checkbox-wrapper')
- .then((elements) => Array.from(elements).map((el) => el.innerText));
- }
+ this.waitForGridDataLoad();
+ }
- getDataGridColumnShowHideOption(option) {
- return this.getDataGridColumnShowHideOptions()
- .should('have.length.gt', 0)
- .then((elements) => Array.from(elements).find((el) => el.innerText === option))
- .find('input');
- }
+ clearSearchField() {
+ this.getDataGridSearchInput().should("exist").clear();
- /**
- * ** Get DataGrid page size selection.
- *
- * @returns {Cypress.Chainable>}
- */
- getDataGridPageSizeSelect() {
- return this.getDataGrid().find('clr-dg-page-size .clr-page-size-select');
- }
+ this.waitForGridDataLoad();
+ }
- getDataJobPage() {
- return cy.get('[data-cy=data-pipelines-job-page]');
- }
+ clearSearchFieldWithButton() {
+ this.getDataGridClearSearchButton().should("exist").click({ force: true });
- // Actions
+ this.waitForGridDataLoad();
+ }
- chooseQuickFilter(filterPosition) {
- this.getQuickFilters()
- .then((filters) => {
- return filters && filters[filterPosition];
- })
- .should('exist')
- .click({ force: true });
+ filterByJobName(jobName) {
+ this.getDataGridJobNameFilter().click({ force: true });
- this.waitForGridDataLoad();
- }
+ this.getDataGridFilterInput().should("be.visible").type(jobName);
- refreshDataGrid() {
- this.getDataGridRefreshButton().should('exist').click({ force: true });
+ this.getContentContainer().should("be.visible").click({ force: true });
- this.waitForGridDataLoad();
- }
+ this.waitForGridDataLoad();
- /**
- * ** Search by job name.
- *
- * @param {string} jobName
- */
- searchByJobName(jobName) {
- this.getDataGridSearchInput().should('exist').type(jobName);
+ this.waitForViewToRenderShort();
+ }
- this.waitForGridDataLoad();
- }
+ filterByJobDescription(description) {
+ this.getDataGridJobDescriptionFilter().click({ force: true });
- clearSearchField() {
- this.getDataGridSearchInput().should('exist').clear();
+ this.getDataGridFilterInput().should("be.visible").type(description);
- this.waitForGridDataLoad();
- }
+ this.getContentContainer().should("be.visible").click({ force: true });
- clearSearchFieldWithButton() {
- this.getDataGridClearSearchButton().should('exist').click({ force: true });
+ this.waitForGridDataLoad();
- this.waitForGridDataLoad();
- }
+ this.waitForViewToRenderShort();
+ }
- filterByJobName(jobName) {
- this.getDataGridJobNameFilter().click({ force: true });
+ sortByJobName() {
+ this.getHeaderColumnJobNameSortBtn().should("exist").click({ force: true });
- this.getDataGridFilterInput().should('be.visible').type(jobName);
+ this.waitForGridDataLoad();
+ }
- this.getContentContainer().should('be.visible').click({ force: true });
+ filterByJobTeamName(teamName) {
+ this.getDataGridJobTeamFilter().click({ force: true });
- this.waitForGridDataLoad();
+ this.getDataGridFilterInput().should("be.visible").type(teamName);
- this.waitForViewToRenderShort();
- }
+ this.getContentContainer().should("be.visible").click({ force: true });
- filterByJobDescription(description) {
- this.getDataGridJobDescriptionFilter().click({ force: true });
+ this.waitForGridDataLoad();
+ }
- this.getDataGridFilterInput().should('be.visible').type(description);
+ sortByJobTeamName() {
+ this.getHeaderColumnJobTeamSortBtn().should("exist").click({ force: true });
- this.getContentContainer().should('be.visible').click({ force: true });
+ this.waitForGridDataLoad();
+ }
- this.waitForGridDataLoad();
+ selectRow(jobName) {
+ this.getDataGridRowByName(jobName)
+ .find(".datagrid-select input")
+ .check({ force: true });
- this.waitForViewToRenderShort();
- }
+ this.waitForViewToRenderShort();
+ }
- sortByJobName() {
- this.getHeaderColumnJobNameSortBtn().should('exist').click({ force: true });
+ openJobDetails(teamName, jobName) {
+ this.getDataGridNavigateBtn(teamName, jobName)
+ .scrollIntoView()
+ .should("exist")
+ .click({ force: true });
- this.waitForGridDataLoad();
- }
+ this.waitForDataJobsApiGetReqInterceptor(4);
- filterByJobTeamName(teamName) {
- this.getDataGridJobTeamFilter().click({ force: true });
+ this.waitForViewToRender();
- this.getDataGridFilterInput().should('be.visible').type(teamName);
+ this.getDataJobPage().should("be.visible");
+ }
- this.getContentContainer().should('be.visible').click({ force: true });
+ toggleColumnShowHidePanel() {
+ this.getDataGridColumnToggle().should("exist").click({ force: true });
- this.waitForGridDataLoad();
- }
+ this.waitForClickThinkingTime();
+ }
- sortByJobTeamName() {
- this.getHeaderColumnJobTeamSortBtn().should('exist').click({ force: true });
+ checkColumnShowHideOption(option) {
+ this.getDataGridColumnShowHideOption(option)
+ .should("exist")
+ .check({ force: true });
- this.waitForGridDataLoad();
- }
+ this.waitForViewToRenderShort();
+ }
- selectRow(jobName) {
- this.getDataGridRowByName(jobName).find('.datagrid-select input').check({ force: true });
+ uncheckColumnShowHideOption(option) {
+ this.getDataGridColumnShowHideOption(option)
+ .should("exist")
+ .uncheck({ force: true });
- this.waitForViewToRenderShort();
- }
+ this.waitForViewToRenderShort();
+ }
- openJobDetails(teamName, jobName) {
- this.getDataGridNavigateBtn(teamName, jobName).scrollIntoView().should('exist').click({ force: true });
+ /**
+ * ** Change DataGrid page size
+ *
+ * - hint options in Clarity are generated with values e.g.
+ * - '0: 25'
+ * - '1: 50'
+ * - '2: 100'
+ *
+ * @param {string} size
+ */
+ changePageSize(size) {
+ this.getDataGridPageSizeSelect()
+ .should("be.visible")
+ .then(($element) => {
+ return cy.wait(1000).then(() => $element);
+ })
+ .select(size);
- this.waitForDataJobsApiGetReqInterceptor(4);
-
- this.waitForViewToRender();
-
- this.getDataJobPage().should('be.visible');
- }
-
- toggleColumnShowHidePanel() {
- this.getDataGridColumnToggle().should('exist').click({ force: true });
-
- this.waitForClickThinkingTime();
- }
-
- checkColumnShowHideOption(option) {
- this.getDataGridColumnShowHideOption(option).should('exist').check({ force: true });
-
- this.waitForViewToRenderShort();
- }
-
- uncheckColumnShowHideOption(option) {
- this.getDataGridColumnShowHideOption(option).should('exist').uncheck({ force: true });
-
- this.waitForViewToRenderShort();
- }
-
- /**
- * ** Change DataGrid page size
- *
- * - hint options in Clarity are generated with values e.g.
- * - '0: 25'
- * - '1: 50'
- * - '2: 100'
- *
- * @param {string} size
- */
- changePageSize(size) {
- this.getDataGridPageSizeSelect()
- .should('be.visible')
- .then(($element) => {
- return cy.wait(1000).then(() => $element);
- })
- .select(size);
-
- this.waitForGridDataLoad();
- }
+ this.waitForGridDataLoad();
+ }
}
diff --git a/projects/frontend/data-pipelines/gui/e2e/support/pages/base/data-pipelines/data-pipelines-base.po.js b/projects/frontend/data-pipelines/gui/e2e/support/pages/base/data-pipelines/data-pipelines-base.po.js
index f18bca99e6..f8bd06788a 100644
--- a/projects/frontend/data-pipelines/gui/e2e/support/pages/base/data-pipelines/data-pipelines-base.po.js
+++ b/projects/frontend/data-pipelines/gui/e2e/support/pages/base/data-pipelines/data-pipelines-base.po.js
@@ -5,502 +5,543 @@
///
-import { TEAM_VDK, TEAM_VDK_DATA_JOB_FAILING, TEAM_VDK_DATA_JOB_TEST_V10, TEAM_VDK_DATA_JOB_TEST_V11, TEAM_VDK_DATA_JOB_TEST_V12, TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V0, TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V1, TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V2 } from '../../../helpers/constants.support';
+import {
+ TEAM_VDK,
+ TEAM_VDK_DATA_JOB_FAILING,
+ TEAM_VDK_DATA_JOB_TEST_V10,
+ TEAM_VDK_DATA_JOB_TEST_V11,
+ TEAM_VDK_DATA_JOB_TEST_V12,
+ TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V0,
+ TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V1,
+ TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V2,
+} from "../../../helpers/constants.support";
-import { applyGlobalEnvSettings } from '../../../../plugins/helpers/util-helpers.plugins';
+import { applyGlobalEnvSettings } from "../../../../plugins/helpers/util-helpers.plugins";
-import { BasePagePO } from '../base-page.po';
+import { BasePagePO } from "../base-page.po";
export class DataPipelinesBasePO extends BasePagePO {
- // Generics
-
- /**
- * ** Returns instance of the page object.
- *
- * @returns {DataPipelinesBasePO}
- */
- static getPage() {
- return new DataPipelinesBasePO();
+ // Generics
+
+ /**
+ * ** Returns instance of the page object.
+ *
+ * @returns {DataPipelinesBasePO}
+ */
+ static getPage() {
+ return new DataPipelinesBasePO();
+ }
+
+ /**
+ * ** Init Http requests interceptors.
+ */
+ static initInterceptors() {
+ super.initInterceptors();
+
+ this.executeCypressCommand("initDataJobDeploymentPatchReqInterceptor");
+ this.executeCypressCommand("initDataJobExecutionPostReqInterceptor");
+ }
+
+ /**
+ * ** Navigate to some url.
+ *
+ * @param {string} url
+ * @param {number} numberOfDataJobsApiGetReqInterceptorWaiting
+ */
+ static navigateToDataJobUrl(
+ url,
+ numberOfDataJobsApiGetReqInterceptorWaiting = 1,
+ ) {
+ this.navigateToUrl(url);
+
+ this.waitForApplicationBootstrap();
+ this.waitForDataJobsApiGetReqInterceptor(
+ numberOfDataJobsApiGetReqInterceptorWaiting,
+ );
+
+ return this.getPage();
+ }
+
+ /**
+ * ** Navigate to some url without bootstrap.
+ *
+ * @param {string} url
+ */
+ static navigateToDataJobUrlNoBootstrap(url) {
+ this.navigateToUrl(url);
+ return this.getPage();
+ }
+
+ /**
+ * ** Wait for Data Job post execution req.
+ *
+ * @return {Cypress.Chainable}
+ */
+ static waitForDataJobExecutionPostReqInterceptor() {
+ return this.executeCypressCommand(
+ "waitForDataJobExecutionPostReqInterceptor",
+ );
+ }
+
+ /**
+ * ** Wait for Data Job patch deployment req.
+ *
+ * @return {Cypress.Chainable}
+ */
+ static waitForDataJobDeploymentPatchReqInterceptor() {
+ return this.executeCypressCommand(
+ "waitForDataJobDeploymentPatchReqInterceptor",
+ );
+ }
+
+ // Plugins invoking
+
+ /**
+ * ** Create long-lived Data Jobs.
+ *
+ * @param {'failing'} instruction
+ * @returns {Cypress.Chainable}
+ */
+ static createLongLivedJobs(...instruction) {
+ const relativePathToFixtures = [];
+ if (instruction.includes("failing")) {
+ relativePathToFixtures.push({
+ pathToFixture: `/base/data-jobs/${TEAM_VDK}/${TEAM_VDK_DATA_JOB_FAILING}.json`,
+ pathToZipFile: `/base/data-jobs/${TEAM_VDK}/${TEAM_VDK_DATA_JOB_FAILING}.zip`,
+ });
}
- /**
- * ** Init Http requests interceptors.
- */
- static initInterceptors() {
- super.initInterceptors();
-
- this.executeCypressCommand('initDataJobDeploymentPatchReqInterceptor');
- this.executeCypressCommand('initDataJobExecutionPostReqInterceptor');
+ return cy.task(
+ "createDeployJobs",
+ {
+ relativePathToFixtures,
+ },
+ { timeout: this.WAIT_EXTRA_LONG_TASK },
+ );
+ }
+
+ /**
+ * ** Create base short-lived test job with deployment.
+ *
+ * - They are created during tests execution and are deleted before and after test suits.
+ * - Executed in context of test environment.
+ *
+ * @param {'v0'|'v1'|'v2'} jobVersion
+ * @returns {Cypress.Chainable}
+ */
+ static createShortLivedTestJobWithDeploy(...jobVersion) {
+ const relativePathToFixtures = [];
+ if (jobVersion.includes("v0")) {
+ relativePathToFixtures.push({
+ pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V0}.json`,
+ pathToZipFile: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V0}.zip`,
+ });
}
- /**
- * ** Navigate to some url.
- *
- * @param {string} url
- * @param {number} numberOfDataJobsApiGetReqInterceptorWaiting
- */
- static navigateToDataJobUrl(url, numberOfDataJobsApiGetReqInterceptorWaiting = 1) {
- this.navigateToUrl(url);
-
- this.waitForApplicationBootstrap();
- this.waitForDataJobsApiGetReqInterceptor(numberOfDataJobsApiGetReqInterceptorWaiting);
-
- return this.getPage();
+ if (jobVersion.includes("v1")) {
+ relativePathToFixtures.push({
+ pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V1}.json`,
+ pathToZipFile: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V1}.zip`,
+ });
}
- /**
- * ** Navigate to some url without bootstrap.
- *
- * @param {string} url
- */
- static navigateToDataJobUrlNoBootstrap(url) {
- this.navigateToUrl(url);
- return this.getPage();
+ if (jobVersion.includes("v2")) {
+ relativePathToFixtures.push({
+ pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V2}.json`,
+ pathToZipFile: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V2}.zip`,
+ });
}
- /**
- * ** Wait for Data Job post execution req.
- *
- * @return {Cypress.Chainable}
- */
- static waitForDataJobExecutionPostReqInterceptor() {
- return this.executeCypressCommand('waitForDataJobExecutionPostReqInterceptor');
+ return cy.task(
+ "createDeployJobs",
+ {
+ relativePathToFixtures,
+ },
+ { timeout: this.WAIT_EXTRA_LONG_TASK },
+ );
+ }
+
+ /**
+ * ** Provide executions for long-lived Data Jobs.
+ *
+ * @param {{job: 'failing'; executions?: number;}} instruction
+ * @returns {Cypress.Chainable}
+ */
+ static provideExecutionsForLongLivedJobs(...instruction) {
+ const relativePathToFixtures = [];
+ const foundFailingIndex = instruction.findIndex((i) => i.job === "failing");
+ if (foundFailingIndex !== -1) {
+ relativePathToFixtures.push({
+ pathToFixture: `/base/data-jobs/${TEAM_VDK}/${TEAM_VDK_DATA_JOB_FAILING}.json`,
+ executions: instruction[foundFailingIndex]?.executions ?? 2,
+ });
}
- /**
- * ** Wait for Data Job patch deployment req.
- *
- * @return {Cypress.Chainable}
- */
- static waitForDataJobDeploymentPatchReqInterceptor() {
- return this.executeCypressCommand('waitForDataJobDeploymentPatchReqInterceptor');
+ return cy.task(
+ "provideDataJobsExecutions",
+ {
+ relativePathToFixtures,
+ },
+ { timeout: DataPipelinesBasePO.WAIT_EXTRA_LONG_TASK },
+ );
+ }
+
+ /**
+ * ** Provide one execution for short-lived Data Job with deployment.
+ *
+ * @param {'v0'|'v1'|'v2'} jobVersion
+ * @returns {Cypress.Chainable}
+ */
+ static provideExecutionsForShortLivedTestJobWithDeploy(...jobVersion) {
+ const relativePathToFixtures = [];
+ if (jobVersion.includes("v0")) {
+ relativePathToFixtures.push({
+ pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V0}.json`,
+ executions: 1,
+ });
}
- // Plugins invoking
-
- /**
- * ** Create long-lived Data Jobs.
- *
- * @param {'failing'} instruction
- * @returns {Cypress.Chainable}
- */
- static createLongLivedJobs(...instruction) {
- const relativePathToFixtures = [];
- if (instruction.includes('failing')) {
- relativePathToFixtures.push({
- pathToFixture: `/base/data-jobs/${TEAM_VDK}/${TEAM_VDK_DATA_JOB_FAILING}.json`,
- pathToZipFile: `/base/data-jobs/${TEAM_VDK}/${TEAM_VDK_DATA_JOB_FAILING}.zip`
- });
- }
-
- return cy.task(
- 'createDeployJobs',
- {
- relativePathToFixtures
- },
- { timeout: this.WAIT_EXTRA_LONG_TASK }
- );
+ if (jobVersion.includes("v1")) {
+ relativePathToFixtures.push({
+ pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V1}.json`,
+ executions: 1,
+ });
}
- /**
- * ** Create base short-lived test job with deployment.
- *
- * - They are created during tests execution and are deleted before and after test suits.
- * - Executed in context of test environment.
- *
- * @param {'v0'|'v1'|'v2'} jobVersion
- * @returns {Cypress.Chainable}
- */
- static createShortLivedTestJobWithDeploy(...jobVersion) {
- const relativePathToFixtures = [];
- if (jobVersion.includes('v0')) {
- relativePathToFixtures.push({
- pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V0}.json`,
- pathToZipFile: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V0}.zip`
- });
- }
-
- if (jobVersion.includes('v1')) {
- relativePathToFixtures.push({
- pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V1}.json`,
- pathToZipFile: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V1}.zip`
- });
- }
-
- if (jobVersion.includes('v2')) {
- relativePathToFixtures.push({
- pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V2}.json`,
- pathToZipFile: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V2}.zip`
- });
- }
-
- return cy.task(
- 'createDeployJobs',
- {
- relativePathToFixtures
- },
- { timeout: this.WAIT_EXTRA_LONG_TASK }
- );
+ if (jobVersion.includes("v2")) {
+ relativePathToFixtures.push({
+ pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V2}.json`,
+ executions: 1,
+ });
}
- /**
- * ** Provide executions for long-lived Data Jobs.
- *
- * @param {{job: 'failing'; executions?: number;}} instruction
- * @returns {Cypress.Chainable}
- */
- static provideExecutionsForLongLivedJobs(...instruction) {
- const relativePathToFixtures = [];
- const foundFailingIndex = instruction.findIndex((i) => i.job === 'failing');
- if (foundFailingIndex !== -1) {
- relativePathToFixtures.push({
- pathToFixture: `/base/data-jobs/${TEAM_VDK}/${TEAM_VDK_DATA_JOB_FAILING}.json`,
- executions: instruction[foundFailingIndex]?.executions ?? 2
- });
- }
-
- return cy.task(
- 'provideDataJobsExecutions',
- {
- relativePathToFixtures
- },
- { timeout: DataPipelinesBasePO.WAIT_EXTRA_LONG_TASK }
- );
+ return cy.task(
+ "provideDataJobsExecutions",
+ {
+ relativePathToFixtures,
+ },
+ { timeout: DataPipelinesBasePO.WAIT_EXTRA_LONG_TASK },
+ );
+ }
+
+ /**
+ * ** Change long-lived Data Job status.
+ *
+ * @param {'failing'} instruction
+ * @param {boolean} status
+ * @returns {Cypress.Chainable}
+ */
+ static changeLongLivedJobStatus(instruction, status) {
+ let pathToFixture;
+ if (instruction === "failing") {
+ pathToFixture = `/base/data-jobs/${TEAM_VDK}/${TEAM_VDK_DATA_JOB_FAILING}.json`;
}
- /**
- * ** Provide one execution for short-lived Data Job with deployment.
- *
- * @param {'v0'|'v1'|'v2'} jobVersion
- * @returns {Cypress.Chainable}
- */
- static provideExecutionsForShortLivedTestJobWithDeploy(...jobVersion) {
- const relativePathToFixtures = [];
- if (jobVersion.includes('v0')) {
- relativePathToFixtures.push({
- pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V0}.json`,
- executions: 1
- });
- }
-
- if (jobVersion.includes('v1')) {
- relativePathToFixtures.push({
- pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V1}.json`,
- executions: 1
- });
- }
-
- if (jobVersion.includes('v2')) {
- relativePathToFixtures.push({
- pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V2}.json`,
- executions: 1
- });
- }
-
- return cy.task(
- 'provideDataJobsExecutions',
- {
- relativePathToFixtures
- },
- { timeout: DataPipelinesBasePO.WAIT_EXTRA_LONG_TASK }
- );
+ return cy.task(
+ "changeJobsStatusesFixtures",
+ {
+ relativePathToFixtures: [
+ {
+ pathToFixture,
+ },
+ ],
+ status,
+ },
+ { timeout: DataPipelinesBasePO.WAIT_LONG_TASK },
+ );
+ }
+
+ /**
+ * ** Change short-lived Data Job with deployment status.
+ *
+ * @param {'v0'|'v1'|'v2'} jobVersion
+ * @param {boolean} status
+ * @returns {Cypress.Chainable}
+ */
+ static changeShortLivedTestJobWithDeployStatus(jobVersion, status) {
+ let jobName;
+
+ if (jobVersion === "v0") {
+ jobName = TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V0;
+ } else if (jobVersion === "v1") {
+ jobName = TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V1;
+ } else if (jobVersion === "v2") {
+ jobName = TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V2;
}
- /**
- * ** Change long-lived Data Job status.
- *
- * @param {'failing'} instruction
- * @param {boolean} status
- * @returns {Cypress.Chainable}
- */
- static changeLongLivedJobStatus(instruction, status) {
- let pathToFixture;
- if (instruction === 'failing') {
- pathToFixture = `/base/data-jobs/${TEAM_VDK}/${TEAM_VDK_DATA_JOB_FAILING}.json`;
- }
-
- return cy.task(
- 'changeJobsStatusesFixtures',
+ return cy.task(
+ "changeJobsStatusesFixtures",
+ {
+ relativePathToFixtures: [
+ {
+ pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${jobName}.json`,
+ },
+ ],
+ status,
+ },
+ { timeout: DataPipelinesBasePO.WAIT_LONG_TASK },
+ );
+ }
+
+ /**
+ * ** Create base short-lived test jobs without deployments.
+ *
+ * - They won't be deployed
+ * - They are created during tests execution and are deleted before and after test suits.
+ * - Executed in context of test environment.
+ *
+ * @returns {Cypress.Chainable}
+ */
+ static createShortLivedTestJobsNoDeploy() {
+ return cy.task(
+ "createDeployJobs",
+ {
+ relativePathToFixtures: [
+ {
+ pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_V10}.json`,
+ },
+ {
+ pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_V11}.json`,
+ },
+ ],
+ },
+ { timeout: DataPipelinesBasePO.WAIT_LONG_TASK },
+ );
+ }
+
+ /**
+ * ** Create additional short-lived test job without deployment.
+ *
+ * - It won't be deployed
+ * - It's created during tests execution and is deleted before and after test suits.
+ * - Executed in context of test environment.
+ *
+ * @returns {Cypress.Chainable}
+ */
+ static createAdditionalShortLivedTestJobsNoDeploy() {
+ return cy
+ .task(
+ "createDeployJobs",
+ {
+ relativePathToFixtures: [
{
- relativePathToFixtures: [
- {
- pathToFixture
- }
- ],
- status
+ pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_V12}.json`,
},
- { timeout: DataPipelinesBasePO.WAIT_LONG_TASK }
- );
+ ],
+ },
+ { timeout: DataPipelinesBasePO.WAIT_LONG_TASK },
+ )
+ .then(() => cy.wait(DataPipelinesBasePO.WAIT_AFTER_API_MODIFY_CALL));
+ }
+
+ /**
+ * ** Wait for Test Data Job existing execution to complete.
+ *
+ * @param {'v0'|'v1'|'v2'} jobVersion
+ */
+ static waitForShortLivedTestJobWithDeployExecutionToComplete(jobVersion) {
+ return this.loadShortLivedTestJobFixtureWithDeploy(jobVersion).then(
+ (jobFixture) =>
+ cy.task(
+ "waitForDataJobExecutionToComplete",
+ {
+ jobFixture,
+ jobExecutionTimeout: 240000,
+ },
+ { timeout: DataPipelinesBasePO.WAIT_LONG_TASK },
+ ),
+ );
+ }
+
+ /**
+ * ** Delete short-lived test jobs.
+ *
+ * - They are created during tests execution and are deleted before and after test suits.
+ * - Executed in context of test environment.
+ *
+ * @param {boolean} isDeleteOptional
+ * @returns {Cypress.Chainable}
+ */
+ static deleteShortLivedTestJobsNoDeploy(isDeleteOptional) {
+ return cy.task(
+ "deleteJobsFixtures",
+ {
+ relativePathToFixtures: [
+ {
+ pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_V10}.json`,
+ },
+ {
+ pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_V11}.json`,
+ },
+ {
+ pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_V12}.json`,
+ },
+ ],
+ optional: isDeleteOptional,
+ },
+ { timeout: DataPipelinesBasePO.WAIT_LONG_TASK },
+ );
+ }
+
+ /**
+ * ** Delete short-lived test job with deployment.
+ *
+ * - They are created during tests execution and are deleted before and after test suits.
+ * - Executed in context of test environment.
+ *
+ * @param {'v0'|'v1'|'v2'} jobVersion
+ * @returns {Cypress.Chainable}
+ */
+ static deleteShortLivedTestJobWithDeploy(...jobVersion) {
+ const relativePathToFixtures = [];
+ if (jobVersion.includes("v0")) {
+ relativePathToFixtures.push({
+ pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V0}.json`,
+ });
}
- /**
- * ** Change short-lived Data Job with deployment status.
- *
- * @param {'v0'|'v1'|'v2'} jobVersion
- * @param {boolean} status
- * @returns {Cypress.Chainable}
- */
- static changeShortLivedTestJobWithDeployStatus(jobVersion, status) {
- let jobName;
-
- if (jobVersion === 'v0') {
- jobName = TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V0;
- } else if (jobVersion === 'v1') {
- jobName = TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V1;
- } else if (jobVersion === 'v2') {
- jobName = TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V2;
- }
-
- return cy.task(
- 'changeJobsStatusesFixtures',
- {
- relativePathToFixtures: [
- {
- pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${jobName}.json`
- }
- ],
- status
- },
- { timeout: DataPipelinesBasePO.WAIT_LONG_TASK }
- );
- }
-
- /**
- * ** Create base short-lived test jobs without deployments.
- *
- * - They won't be deployed
- * - They are created during tests execution and are deleted before and after test suits.
- * - Executed in context of test environment.
- *
- * @returns {Cypress.Chainable}
- */
- static createShortLivedTestJobsNoDeploy() {
- return cy.task(
- 'createDeployJobs',
- {
- relativePathToFixtures: [
- {
- pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_V10}.json`
- },
- {
- pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_V11}.json`
- }
- ]
- },
- { timeout: DataPipelinesBasePO.WAIT_LONG_TASK }
- );
+ if (jobVersion.includes("v1")) {
+ relativePathToFixtures.push({
+ pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V1}.json`,
+ });
}
- /**
- * ** Create additional short-lived test job without deployment.
- *
- * - It won't be deployed
- * - It's created during tests execution and is deleted before and after test suits.
- * - Executed in context of test environment.
- *
- * @returns {Cypress.Chainable}
- */
- static createAdditionalShortLivedTestJobsNoDeploy() {
- return cy
- .task(
- 'createDeployJobs',
- {
- relativePathToFixtures: [
- {
- pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_V12}.json`
- }
- ]
- },
- { timeout: DataPipelinesBasePO.WAIT_LONG_TASK }
- )
- .then(() => cy.wait(DataPipelinesBasePO.WAIT_AFTER_API_MODIFY_CALL));
+ if (jobVersion.includes("v2")) {
+ relativePathToFixtures.push({
+ pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V2}.json`,
+ });
}
- /**
- * ** Wait for Test Data Job existing execution to complete.
- *
- * @param {'v0'|'v1'|'v2'} jobVersion
- */
- static waitForShortLivedTestJobWithDeployExecutionToComplete(jobVersion) {
- return this.loadShortLivedTestJobFixtureWithDeploy(jobVersion).then((jobFixture) =>
- cy.task(
- 'waitForDataJobExecutionToComplete',
- {
- jobFixture,
- jobExecutionTimeout: 240000
- },
- { timeout: DataPipelinesBasePO.WAIT_LONG_TASK }
- )
- );
+ return cy.task(
+ "deleteJobsFixtures",
+ {
+ relativePathToFixtures,
+ },
+ { timeout: DataPipelinesBasePO.WAIT_LONG_TASK },
+ );
+ }
+
+ /**
+ * ** Load long-lived failing Data Job fixture.
+ *
+ * @returns {Cypress.Chainable<{job_name:string; description:string; team:string; config:{db_default_type:string; contacts:{}; schedule:{schedule_cron:string}; generate_keytab:boolean; enable_execution_notifications:boolean}}>}
+ */
+ static loadLongLivedFailingJobFixture() {
+ return cy
+ .fixture(`/base/data-jobs/${TEAM_VDK}/${TEAM_VDK_DATA_JOB_FAILING}.json`)
+ .then((fixture) => applyGlobalEnvSettings(fixture));
+ }
+
+ /**
+ * ** Load short-lived test Data Job with deployment fixture.
+ *
+ * @param {'v0'|'v1'|'v2'} jobVersion
+ * @returns {Cypress.Chainable<{job_name:string; description:string; team:string; config:{db_default_type:string; contacts:{}; schedule:{schedule_cron:string}; generate_keytab:boolean; enable_execution_notifications:boolean}}>}
+ */
+ static loadShortLivedTestJobFixtureWithDeploy(jobVersion) {
+ let jobName;
+
+ if (jobVersion === "v0") {
+ jobName = TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V0;
+ } else if (jobVersion === "v1") {
+ jobName = TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V1;
+ } else if (jobVersion === "v2") {
+ jobName = TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V2;
}
- /**
- * ** Delete short-lived test jobs.
- *
- * - They are created during tests execution and are deleted before and after test suits.
- * - Executed in context of test environment.
- *
- * @param {boolean} isDeleteOptional
- * @returns {Cypress.Chainable}
- */
- static deleteShortLivedTestJobsNoDeploy(isDeleteOptional) {
- return cy.task(
- 'deleteJobsFixtures',
- {
- relativePathToFixtures: [
- {
- pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_V10}.json`
- },
- {
- pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_V11}.json`
- },
- {
- pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_V12}.json`
- }
- ],
- optional: isDeleteOptional
- },
- { timeout: DataPipelinesBasePO.WAIT_LONG_TASK }
- );
- }
-
- /**
- * ** Delete short-lived test job with deployment.
- *
- * - They are created during tests execution and are deleted before and after test suits.
- * - Executed in context of test environment.
- *
- * @param {'v0'|'v1'|'v2'} jobVersion
- * @returns {Cypress.Chainable}
- */
- static deleteShortLivedTestJobWithDeploy(...jobVersion) {
- const relativePathToFixtures = [];
- if (jobVersion.includes('v0')) {
- relativePathToFixtures.push({
- pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V0}.json`
- });
- }
-
- if (jobVersion.includes('v1')) {
- relativePathToFixtures.push({
- pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V1}.json`
- });
- }
-
- if (jobVersion.includes('v2')) {
- relativePathToFixtures.push({
- pathToFixture: `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V2}.json`
- });
- }
-
- return cy.task(
- 'deleteJobsFixtures',
- {
- relativePathToFixtures
- },
- { timeout: DataPipelinesBasePO.WAIT_LONG_TASK }
- );
- }
-
- /**
- * ** Load long-lived failing Data Job fixture.
- *
- * @returns {Cypress.Chainable<{job_name:string; description:string; team:string; config:{db_default_type:string; contacts:{}; schedule:{schedule_cron:string}; generate_keytab:boolean; enable_execution_notifications:boolean}}>}
- */
- static loadLongLivedFailingJobFixture() {
- return cy.fixture(`/base/data-jobs/${TEAM_VDK}/${TEAM_VDK_DATA_JOB_FAILING}.json`).then((fixture) => applyGlobalEnvSettings(fixture));
- }
-
- /**
- * ** Load short-lived test Data Job with deployment fixture.
- *
- * @param {'v0'|'v1'|'v2'} jobVersion
- * @returns {Cypress.Chainable<{job_name:string; description:string; team:string; config:{db_default_type:string; contacts:{}; schedule:{schedule_cron:string}; generate_keytab:boolean; enable_execution_notifications:boolean}}>}
- */
- static loadShortLivedTestJobFixtureWithDeploy(jobVersion) {
- let jobName;
-
- if (jobVersion === 'v0') {
- jobName = TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V0;
- } else if (jobVersion === 'v1') {
- jobName = TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V1;
- } else if (jobVersion === 'v2') {
- jobName = TEAM_VDK_DATA_JOB_TEST_WITH_DEPLOY_V2;
- }
-
- return cy.fixture(`/base/data-jobs/${TEAM_VDK}/short-lived/${jobName}.json`).then((fixture) => applyGlobalEnvSettings(fixture));
- }
-
- /**
- * ** Load short-lived test Data Jobs fixture.
- *
- * @returns {Cypress.Chainable>}
- */
- static loadShortLivedTestJobsFixtureNoDeploy() {
- return cy.fixture(`/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_V10}.json`).then((fixture1) => {
- return cy.fixture(`/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_V11}.json`).then((fixture2) => {
- return cy.fixture(`/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_V12}.json`).then((fixture3) => {
- return [applyGlobalEnvSettings(fixture1), applyGlobalEnvSettings(fixture2), applyGlobalEnvSettings(fixture3)];
- });
- });
- });
- }
-
- /**
- * ** Wait for Data Job patch deployment req.
- *
- * @return {Cypress.Chainable}
- */
- waitForDataJobDeploymentPatchReqInterceptor() {
- return DataPipelinesBasePO.waitForDataJobDeploymentPatchReqInterceptor();
- }
-
- /**
- * ** Wait for Data Job patch deployment req.
- *
- * @return {Cypress.Chainable}
- */
- waitForDataJobExecutionPostReqInterceptor() {
- return DataPipelinesBasePO.waitForDataJobExecutionPostReqInterceptor();
- }
-
- /**
- * ** Wait API request to finish, then grid to load and finally additional short wait rows to be rendered.
- *
- * @return {Cypress.Chainable}
- */
- waitForGridDataLoad() {
- return this.waitForDataJobsApiGetReqInterceptor()
- .then(() => this.waitForGridToLoad(null))
- .then(() => this.waitForViewToRenderShort());
- }
-
- /* Selectors */
-
- getContentContainer() {
- return cy.get('div.content-container');
+ return cy
+ .fixture(`/base/data-jobs/${TEAM_VDK}/short-lived/${jobName}.json`)
+ .then((fixture) => applyGlobalEnvSettings(fixture));
+ }
+
+ /**
+ * ** Load short-lived test Data Jobs fixture.
+ *
+ * @returns {Cypress.Chainable>}
+ */
+ static loadShortLivedTestJobsFixtureNoDeploy() {
+ return cy
+ .fixture(
+ `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_V10}.json`,
+ )
+ .then((fixture1) => {
+ return cy
+ .fixture(
+ `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_V11}.json`,
+ )
+ .then((fixture2) => {
+ return cy
+ .fixture(
+ `/base/data-jobs/${TEAM_VDK}/short-lived/${TEAM_VDK_DATA_JOB_TEST_V12}.json`,
+ )
+ .then((fixture3) => {
+ return [
+ applyGlobalEnvSettings(fixture1),
+ applyGlobalEnvSettings(fixture2),
+ applyGlobalEnvSettings(fixture3),
+ ];
+ });
+ });
+ });
+ }
+
+ /**
+ * ** Wait for Data Job patch deployment req.
+ *
+ * @return {Cypress.Chainable}
+ */
+ waitForDataJobDeploymentPatchReqInterceptor() {
+ return DataPipelinesBasePO.waitForDataJobDeploymentPatchReqInterceptor();
+ }
+
+ /**
+ * ** Wait for Data Job patch deployment req.
+ *
+ * @return {Cypress.Chainable}
+ */
+ waitForDataJobExecutionPostReqInterceptor() {
+ return DataPipelinesBasePO.waitForDataJobExecutionPostReqInterceptor();
+ }
+
+ /**
+ * ** Wait API request to finish, then grid to load and finally additional short wait rows to be rendered.
+ *
+ * @return {Cypress.Chainable}
+ */
+ waitForGridDataLoad() {
+ return this.waitForDataJobsApiGetReqInterceptor()
+ .then(() => this.waitForGridToLoad(null))
+ .then(() => this.waitForViewToRenderShort());
+ }
+
+ /* Selectors */
+
+ getContentContainer() {
+ return cy.get("div.content-container");
+ }
+
+ /* Actions */
+
+ /**
+ ** Confirm action in dialog.
+ *
+ * @param {() => void} interceptor
+ */
+ confirmInConfirmDialog(interceptor) {
+ cy.get("[data-cy=confirmation-dialog-ok-btn]")
+ .should("exist")
+ .click({ force: true });
+
+ if (interceptor) {
+ interceptor();
}
- /* Actions */
+ this.waitForViewToRenderShort();
+ }
- /**
- ** Confirm action in dialog.
- *
- * @param {() => void} interceptor
- */
- confirmInConfirmDialog(interceptor) {
- cy.get('[data-cy=confirmation-dialog-ok-btn]').should('exist').click({ force: true });
+ clickOnContentContainer() {
+ this.getContentContainer().should("exist").click({ force: true });
- if (interceptor) {
- interceptor();
- }
-
- this.waitForViewToRenderShort();
- }
-
- clickOnContentContainer() {
- this.getContentContainer().should('exist').click({ force: true });
-
- this.waitForSmartDelay();
- }
+ this.waitForSmartDelay();
+ }
}
diff --git a/projects/frontend/data-pipelines/gui/e2e/support/pages/explore/data-jobs/data-jobs.po.js b/projects/frontend/data-pipelines/gui/e2e/support/pages/explore/data-jobs/data-jobs.po.js
index 6420b5f2ae..7cd8b32aef 100644
--- a/projects/frontend/data-pipelines/gui/e2e/support/pages/explore/data-jobs/data-jobs.po.js
+++ b/projects/frontend/data-pipelines/gui/e2e/support/pages/explore/data-jobs/data-jobs.po.js
@@ -5,76 +5,82 @@
///
-import { DataJobsBasePO } from '../../base/data-pipelines/data-jobs-base.po';
+import { DataJobsBasePO } from "../../base/data-pipelines/data-jobs-base.po";
export class DataJobsExplorePage extends DataJobsBasePO {
- /**
- * ** Returns instance of the page object.
- *
- * @returns {DataJobsExplorePage}
- */
- static getPage() {
- return new DataJobsExplorePage();
- }
-
- /**
- * @inheritDoc
- * @return {DataJobsExplorePage}
- */
- static navigateWithSideMenu() {
- return super.navigateWithSideMenu('navLinkExploreDataJobs', 'openExplore', {
- before: () => {
- this.waitForApplicationBootstrap();
- this.waitForDataJobsApiGetReqInterceptor(3);
- },
- after: () => {
- this.waitForDataJobsApiGetReqInterceptor();
+ /**
+ * ** Returns instance of the page object.
+ *
+ * @returns {DataJobsExplorePage}
+ */
+ static getPage() {
+ return new DataJobsExplorePage();
+ }
- const page = this.getPage();
- page.waitForGridToLoad(null);
- page.waitForViewToRenderShort();
- }
- });
- }
+ /**
+ * @inheritDoc
+ * @return {DataJobsExplorePage}
+ */
+ static navigateWithSideMenu() {
+ return super.navigateWithSideMenu("navLinkExploreDataJobs", "openExplore", {
+ before: () => {
+ this.waitForApplicationBootstrap();
+ this.waitForDataJobsApiGetReqInterceptor(3);
+ },
+ after: () => {
+ this.waitForDataJobsApiGetReqInterceptor();
- /**
- * ** Navigate to Explore Data Jobs.
- *
- * @return {DataJobsExplorePage}
- */
- static navigateTo() {
- /**
- * @type {DataJobsExplorePage}
- */
- const page = super.navigateTo('explore');
+ const page = this.getPage();
page.waitForGridToLoad(null);
page.waitForViewToRenderShort();
+ },
+ });
+ }
- return page;
- }
-
+ /**
+ * ** Navigate to Explore Data Jobs.
+ *
+ * @return {DataJobsExplorePage}
+ */
+ static navigateTo() {
/**
- * ** Wait until Data grid is loaded.
- *
- * @param {string} contextSelector
- * @param {number} timeout
- * @returns {Cypress.Chainable}
+ * @type {DataJobsExplorePage}
*/
- waitForGridToLoad(contextSelector, timeout = DataJobsBasePO.WAIT_SHORT_TASK) {
- return this._waitForGridToLoad('data-pipelines-explore-data-jobs', timeout);
- }
+ const page = super.navigateTo("explore");
+ page.waitForGridToLoad(null);
+ page.waitForViewToRenderShort();
+
+ return page;
+ }
+
+ /**
+ * ** Wait until Data grid is loaded.
+ *
+ * @param {string} contextSelector
+ * @param {number} timeout
+ * @returns {Cypress.Chainable}
+ */
+ waitForGridToLoad(contextSelector, timeout = DataJobsBasePO.WAIT_SHORT_TASK) {
+ return this._waitForGridToLoad("data-pipelines-explore-data-jobs", timeout);
+ }
- // Selectors
+ // Selectors
- getDataGrid() {
- return cy.get('[data-cy=data-pipelines-explore-grid]');
- }
+ getDataGrid() {
+ return cy.get("[data-cy=data-pipelines-explore-grid]");
+ }
- getDataGridNavigateBtn(team, job) {
- return cy.get('[data-cy=data-pipelines-explore-grid-details-link][data-job-params="' + team + ';' + job + '"]');
- }
+ getDataGridNavigateBtn(team, job) {
+ return cy.get(
+ '[data-cy=data-pipelines-explore-grid-details-link][data-job-params="' +
+ team +
+ ";" +
+ job +
+ '"]',
+ );
+ }
- getDataGridRefreshButton() {
- return cy.get('[data-cy=data-pipelines-explore-refresh-btn]');
- }
+ getDataGridRefreshButton() {
+ return cy.get("[data-cy=data-pipelines-explore-refresh-btn]");
+ }
}
diff --git a/projects/frontend/data-pipelines/gui/e2e/support/pages/explore/data-jobs/details/data-job-details.po.js b/projects/frontend/data-pipelines/gui/e2e/support/pages/explore/data-jobs/details/data-job-details.po.js
index 473ec16b82..b6e5c70024 100644
--- a/projects/frontend/data-pipelines/gui/e2e/support/pages/explore/data-jobs/details/data-job-details.po.js
+++ b/projects/frontend/data-pipelines/gui/e2e/support/pages/explore/data-jobs/details/data-job-details.po.js
@@ -5,25 +5,25 @@
///
-import { DataJobDetailsBasePO } from '../../../base/data-pipelines/data-job-details-base.po';
+import { DataJobDetailsBasePO } from "../../../base/data-pipelines/data-job-details-base.po";
export class DataJobExploreDetailsPage extends DataJobDetailsBasePO {
- /**
- * ** Returns instance of the page object.
- *
- * @returns {DataJobExploreDetailsPage}
- */
- static getPage() {
- return new DataJobExploreDetailsPage();
- }
+ /**
+ * ** Returns instance of the page object.
+ *
+ * @returns {DataJobExploreDetailsPage}
+ */
+ static getPage() {
+ return new DataJobExploreDetailsPage();
+ }
- /**
- * @inheritDoc
- * @param {string} teamName
- * @param {string} jobName
- * @return {DataJobExploreDetailsPage}
- */
- static navigateTo(teamName, jobName) {
- return super.navigateTo('explore', teamName, jobName);
- }
+ /**
+ * @inheritDoc
+ * @param {string} teamName
+ * @param {string} jobName
+ * @return {DataJobExploreDetailsPage}
+ */
+ static navigateTo(teamName, jobName) {
+ return super.navigateTo("explore", teamName, jobName);
+ }
}
diff --git a/projects/frontend/data-pipelines/gui/e2e/support/pages/explore/data-jobs/executions/data-job-executions.po.js b/projects/frontend/data-pipelines/gui/e2e/support/pages/explore/data-jobs/executions/data-job-executions.po.js
index defb7c56f3..b2b1a20b01 100644
--- a/projects/frontend/data-pipelines/gui/e2e/support/pages/explore/data-jobs/executions/data-job-executions.po.js
+++ b/projects/frontend/data-pipelines/gui/e2e/support/pages/explore/data-jobs/executions/data-job-executions.po.js
@@ -5,25 +5,25 @@
///
-import { DataJobBasePO } from '../../../base/data-pipelines/data-job-base.po';
+import { DataJobBasePO } from "../../../base/data-pipelines/data-job-base.po";
export class DataJobExploreExecutionsPage extends DataJobBasePO {
- /**
- * ** Returns instance of the page object.
- *
- * @returns {DataJobExploreExecutionsPage}
- */
- static getPage() {
- return new DataJobExploreExecutionsPage();
- }
+ /**
+ * ** Returns instance of the page object.
+ *
+ * @returns {DataJobExploreExecutionsPage}
+ */
+ static getPage() {
+ return new DataJobExploreExecutionsPage();
+ }
- /**
- * @inheritDoc
- * @param {string} teamName
- * @param {string} jobName
- * @return {DataJobExploreExecutionsPage}
- */
- static navigateTo(teamName, jobName) {
- return super.navigateTo('explore', teamName, jobName, 'executions');
- }
+ /**
+ * @inheritDoc
+ * @param {string} teamName
+ * @param {string} jobName
+ * @return {DataJobExploreExecutionsPage}
+ */
+ static navigateTo(teamName, jobName) {
+ return super.navigateTo("explore", teamName, jobName, "executions");
+ }
}
diff --git a/projects/frontend/data-pipelines/gui/e2e/support/pages/get-started/get-started-page-data-jobs-health-overview.po.js b/projects/frontend/data-pipelines/gui/e2e/support/pages/get-started/get-started-page-data-jobs-health-overview.po.js
index 35a4f7b7bd..c047ca9a69 100644
--- a/projects/frontend/data-pipelines/gui/e2e/support/pages/get-started/get-started-page-data-jobs-health-overview.po.js
+++ b/projects/frontend/data-pipelines/gui/e2e/support/pages/get-started/get-started-page-data-jobs-health-overview.po.js
@@ -5,191 +5,209 @@
///
-import { DataPipelinesBasePO } from '../base/data-pipelines/data-pipelines-base.po';
+import { DataPipelinesBasePO } from "../base/data-pipelines/data-pipelines-base.po";
export class GetStartedDataJobsHealthOverviewWidgetPO extends DataPipelinesBasePO {
- /**
- * ** Returns instance of the page object.
- *
- * @returns {GetStartedDataJobsHealthOverviewWidgetPO}
- */
- static getPage() {
- return new GetStartedDataJobsHealthOverviewWidgetPO();
- }
-
- /**
- * ** Navigate to home page through URL and return instance of page object.
- *
- * @type {GetStartedDataJobsHealthOverviewWidgetPO}
- */
- static navigateTo() {
- cy.visit('/get-started');
-
- this.waitForApplicationBootstrap();
- this.waitForDataJobsApiGetReqInterceptor(3);
-
- this.waitForViewToRenderShort();
-
- return this.getPage();
- }
-
- /**
- * ** Get Data jobs health panel.
- *
- * @returns {Cypress.Chainable>}
- */
- getDataJobsHealthPanel() {
- return cy.get('[data-cy=dp-data-jobs-health-panel]');
- }
-
- /**
- * ** Get Execution status gauge Widget.
- *
- * @returns {Cypress.Chainable>}
- */
- getExecutionStatusGaugeWidget() {
- return this.getDataJobsHealthPanel().should('exist').find('lib-widget-execution-status-gauge');
- }
-
- /**
- * ** Get percentage of successful executions against total from Execution status gauge Widget.
- *
- * @returns {Cypress.Chainable}
- */
- getExecutionsSuccessPercentage() {
- return this.getExecutionStatusGaugeWidget()
- .should('exist')
- .find('[data-cy=dp-jobs-executions-status-gauge-widget-percentage]')
- .invoke('text')
- .invoke('trim')
- .invoke('replace', /%/, '')
- .then((value) => +value);
- }
-
- /**
- * ** Get number of failed executions from Execution status gauge Widget.
- *
- * @returns {Cypress.Chainable}
- */
- getNumberOfFailedExecutions() {
- return this.getExecutionStatusGaugeWidget()
- .should('exist')
- .find('.value-current')
- .invoke('text')
- .invoke('trim')
- .invoke('replace', /\s\w+/, '')
- .then((value) => +value);
- }
-
- /**
- * ** Get number of total executions from Execution status gauge Widget.
- *
- * @returns {Cypress.Chainable}
- */
- getExecutionsTotal() {
- return this.getExecutionStatusGaugeWidget()
- .should('exist')
- .find('[data-cy=dp-jobs-executions-status-gauge-widget-total]')
- .invoke('text')
- .invoke('trim')
- .invoke('replace', /\s\w+/, '')
- .then((value) => +value);
- }
-
- /**
- * ** Get Failing Data jobs Widget.
- *
- * @returns {Cypress.Chainable>}
- */
- getFailingJobsWidget() {
- return this.getDataJobsHealthPanel().should('exist').find('lib-data-jobs-failed-widget');
- }
-
- /**
- * ** Get all Data jobs from Failing Data jobs Widget.
- *
- * @returns {Cypress.Chainable>}
- */
- getAllFailingJobs() {
- return this.getFailingJobsWidget().should('exist').find('clr-dg-row clr-dg-cell.job-name-column');
- }
-
- /**
- * ** Get all Data jobs links from Failing Data jobs Widget.
- *
- * @returns {Cypress.Chainable>}
- */
- getAllFailingJobsLinks() {
- return this.getFailingJobsWidget().should('exist').find('[data-cy=dp-failed-data-jobs-widget-job-name-link]');
- }
-
- /**
- * ** Get Most Recent Failing Data jobs Widget.
- *
- * @returns {Cypress.Chainable>}
- */
- getMostRecentFailingJobsWidget() {
- return this.getDataJobsHealthPanel().should('exist').find('lib-data-jobs-executions-widget');
- }
-
- /**
- * ** Get all Data jobs from Most Recent Failing Data jobs Widget.
- *
- * @returns {Cypress.Chainable>}
- */
- getAllMostRecentFailingJobs() {
- return this.getMostRecentFailingJobsWidget().should('exist').find('clr-dg-row clr-dg-cell.job-name-column');
- }
-
- /**
- * ** Get all executions from Most Recent Failing Data jobs executions Widget.
- *
- * @returns {Cypress.Chainable>}
- */
- getAllMostRecentFailingJobsLinks() {
- return this.getMostRecentFailingJobsWidget().should('exist').find('[data-cy=dp-failed-data-jobs-executions-widget-job-name-link]');
- }
-
- // Actions
-
- navigateToFailingJobDetails(jobName) {
- this._navigateToDataJob(this.getAllFailingJobsLinks(), jobName, 4);
- }
-
- navigateToMostRecentFailingJobExecutions(jobName) {
- this._navigateToDataJob(this.getAllMostRecentFailingJobsLinks(), jobName, 3);
- }
-
- /**
- * ** Navigate to Data job
- *
- * @param {Cypress.Chainable>} chainable
- * @param {string} jobName
- * @param {number} numberOfReqToWait
- * @private
- */
- _navigateToDataJob(chainable, jobName, numberOfReqToWait = 3) {
- chainable
- .then((elements) => {
- /**
- * @type {HTMLElement}
- */
- let foundElement;
- elements.each((_index, el) => {
- if (el.innerText.trim().includes(jobName)) {
- foundElement = el;
-
- return false;
- }
- });
-
- return foundElement;
- })
- .should('exist')
- .click({ force: true });
-
- this.waitForDataJobsApiGetReqInterceptor(numberOfReqToWait);
-
- this.waitForViewToRender();
- }
+ /**
+ * ** Returns instance of the page object.
+ *
+ * @returns {GetStartedDataJobsHealthOverviewWidgetPO}
+ */
+ static getPage() {
+ return new GetStartedDataJobsHealthOverviewWidgetPO();
+ }
+
+ /**
+ * ** Navigate to home page through URL and return instance of page object.
+ *
+ * @type {GetStartedDataJobsHealthOverviewWidgetPO}
+ */
+ static navigateTo() {
+ cy.visit("/get-started");
+
+ this.waitForApplicationBootstrap();
+ this.waitForDataJobsApiGetReqInterceptor(3);
+
+ this.waitForViewToRenderShort();
+
+ return this.getPage();
+ }
+
+ /**
+ * ** Get Data jobs health panel.
+ *
+ * @returns {Cypress.Chainable>}
+ */
+ getDataJobsHealthPanel() {
+ return cy.get("[data-cy=dp-data-jobs-health-panel]");
+ }
+
+ /**
+ * ** Get Execution status gauge Widget.
+ *
+ * @returns {Cypress.Chainable>}
+ */
+ getExecutionStatusGaugeWidget() {
+ return this.getDataJobsHealthPanel()
+ .should("exist")
+ .find("lib-widget-execution-status-gauge");
+ }
+
+ /**
+ * ** Get percentage of successful executions against total from Execution status gauge Widget.
+ *
+ * @returns {Cypress.Chainable}
+ */
+ getExecutionsSuccessPercentage() {
+ return this.getExecutionStatusGaugeWidget()
+ .should("exist")
+ .find("[data-cy=dp-jobs-executions-status-gauge-widget-percentage]")
+ .invoke("text")
+ .invoke("trim")
+ .invoke("replace", /%/, "")
+ .then((value) => +value);
+ }
+
+ /**
+ * ** Get number of failed executions from Execution status gauge Widget.
+ *
+ * @returns {Cypress.Chainable}
+ */
+ getNumberOfFailedExecutions() {
+ return this.getExecutionStatusGaugeWidget()
+ .should("exist")
+ .find(".value-current")
+ .invoke("text")
+ .invoke("trim")
+ .invoke("replace", /\s\w+/, "")
+ .then((value) => +value);
+ }
+
+ /**
+ * ** Get number of total executions from Execution status gauge Widget.
+ *
+ * @returns {Cypress.Chainable}
+ */
+ getExecutionsTotal() {
+ return this.getExecutionStatusGaugeWidget()
+ .should("exist")
+ .find("[data-cy=dp-jobs-executions-status-gauge-widget-total]")
+ .invoke("text")
+ .invoke("trim")
+ .invoke("replace", /\s\w+/, "")
+ .then((value) => +value);
+ }
+
+ /**
+ * ** Get Failing Data jobs Widget.
+ *
+ * @returns {Cypress.Chainable>}
+ */
+ getFailingJobsWidget() {
+ return this.getDataJobsHealthPanel()
+ .should("exist")
+ .find("lib-data-jobs-failed-widget");
+ }
+
+ /**
+ * ** Get all Data jobs from Failing Data jobs Widget.
+ *
+ * @returns {Cypress.Chainable>}
+ */
+ getAllFailingJobs() {
+ return this.getFailingJobsWidget()
+ .should("exist")
+ .find("clr-dg-row clr-dg-cell.job-name-column");
+ }
+
+ /**
+ * ** Get all Data jobs links from Failing Data jobs Widget.
+ *
+ * @returns {Cypress.Chainable>}
+ */
+ getAllFailingJobsLinks() {
+ return this.getFailingJobsWidget()
+ .should("exist")
+ .find("[data-cy=dp-failed-data-jobs-widget-job-name-link]");
+ }
+
+ /**
+ * ** Get Most Recent Failing Data jobs Widget.
+ *
+ * @returns {Cypress.Chainable>}
+ */
+ getMostRecentFailingJobsWidget() {
+ return this.getDataJobsHealthPanel()
+ .should("exist")
+ .find("lib-data-jobs-executions-widget");
+ }
+
+ /**
+ * ** Get all Data jobs from Most Recent Failing Data jobs Widget.
+ *
+ * @returns {Cypress.Chainable>}
+ */
+ getAllMostRecentFailingJobs() {
+ return this.getMostRecentFailingJobsWidget()
+ .should("exist")
+ .find("clr-dg-row clr-dg-cell.job-name-column");
+ }
+
+ /**
+ * ** Get all executions from Most Recent Failing Data jobs executions Widget.
+ *
+ * @returns {Cypress.Chainable>}
+ */
+ getAllMostRecentFailingJobsLinks() {
+ return this.getMostRecentFailingJobsWidget()
+ .should("exist")
+ .find("[data-cy=dp-failed-data-jobs-executions-widget-job-name-link]");
+ }
+
+ // Actions
+
+ navigateToFailingJobDetails(jobName) {
+ this._navigateToDataJob(this.getAllFailingJobsLinks(), jobName, 4);
+ }
+
+ navigateToMostRecentFailingJobExecutions(jobName) {
+ this._navigateToDataJob(
+ this.getAllMostRecentFailingJobsLinks(),
+ jobName,
+ 3,
+ );
+ }
+
+ /**
+ * ** Navigate to Data job
+ *
+ * @param {Cypress.Chainable>} chainable
+ * @param {string} jobName
+ * @param {number} numberOfReqToWait
+ * @private
+ */
+ _navigateToDataJob(chainable, jobName, numberOfReqToWait = 3) {
+ chainable
+ .then((elements) => {
+ /**
+ * @type {HTMLElement}
+ */
+ let foundElement;
+ elements.each((_index, el) => {
+ if (el.innerText.trim().includes(jobName)) {
+ foundElement = el;
+
+ return false;
+ }
+ });
+
+ return foundElement;
+ })
+ .should("exist")
+ .click({ force: true });
+
+ this.waitForDataJobsApiGetReqInterceptor(numberOfReqToWait);
+
+ this.waitForViewToRender();
+ }
}
diff --git a/projects/frontend/data-pipelines/gui/e2e/support/pages/get-started/get-started-page.po.js b/projects/frontend/data-pipelines/gui/e2e/support/pages/get-started/get-started-page.po.js
index 729a399ebd..75c38b9d6f 100644
--- a/projects/frontend/data-pipelines/gui/e2e/support/pages/get-started/get-started-page.po.js
+++ b/projects/frontend/data-pipelines/gui/e2e/support/pages/get-started/get-started-page.po.js
@@ -5,42 +5,42 @@
///
-import { BasePagePO } from '../base/base-page.po';
+import { BasePagePO } from "../base/base-page.po";
export class GetStartedPagePO extends BasePagePO {
- /**
- * ** Returns instance of the page object.
- *
- * @returns {GetStartedPagePO}
- */
- static getPage() {
- return new GetStartedPagePO();
- }
-
- /**
- * ** Navigate to home page through URL and return instance of page object.
- *
- * @type {GetStartedPagePO}
- */
- static navigateTo() {
- cy.visit('/get-started');
-
- this.waitForApplicationBootstrap();
- this.waitForDataJobsApiGetReqInterceptor(3);
-
- this.waitForViewToRenderShort();
-
- return this.getPage();
- }
-
- /**
- * ** Navigate to home page through URL and return instance of page object.
- * ** Do not wait for bootstrap and interceptors
- * @type {GetStartedPagePO}
- */
- static navigateToNoBootstrap() {
- cy.visit('/get-started');
- this.waitForViewToRenderShort();
- return this.getPage();
- }
+ /**
+ * ** Returns instance of the page object.
+ *
+ * @returns {GetStartedPagePO}
+ */
+ static getPage() {
+ return new GetStartedPagePO();
+ }
+
+ /**
+ * ** Navigate to home page through URL and return instance of page object.
+ *
+ * @type {GetStartedPagePO}
+ */
+ static navigateTo() {
+ cy.visit("/get-started");
+
+ this.waitForApplicationBootstrap();
+ this.waitForDataJobsApiGetReqInterceptor(3);
+
+ this.waitForViewToRenderShort();
+
+ return this.getPage();
+ }
+
+ /**
+ * ** Navigate to home page through URL and return instance of page object.
+ * ** Do not wait for bootstrap and interceptors
+ * @type {GetStartedPagePO}
+ */
+ static navigateToNoBootstrap() {
+ cy.visit("/get-started");
+ this.waitForViewToRenderShort();
+ return this.getPage();
+ }
}
diff --git a/projects/frontend/data-pipelines/gui/e2e/support/pages/manage/data-jobs/data-jobs.po.js b/projects/frontend/data-pipelines/gui/e2e/support/pages/manage/data-jobs/data-jobs.po.js
index ebbb755c83..af93aa68a5 100644
--- a/projects/frontend/data-pipelines/gui/e2e/support/pages/manage/data-jobs/data-jobs.po.js
+++ b/projects/frontend/data-pipelines/gui/e2e/support/pages/manage/data-jobs/data-jobs.po.js
@@ -5,159 +5,170 @@
///
-import { DataJobsBasePO } from '../../base/data-pipelines/data-jobs-base.po';
+import { DataJobsBasePO } from "../../base/data-pipelines/data-jobs-base.po";
export class DataJobsManagePage extends DataJobsBasePO {
- /**
- * ** Returns instance of the page object.
- *
- * @returns {DataJobsManagePage}
- */
- static getPage() {
- return new DataJobsManagePage();
- }
-
- /**
- * ** Navigate to page with provided nav link id through side menu navigation, choose Team, and return instance of page object.
- *
- * @return {DataJobsManagePage}
- */
- static navigateWithSideMenu() {
- return super.navigateWithSideMenu('navLinkManageDataJobs', 'openManage', {
- before: () => {
- this.waitForApplicationBootstrap();
- this.waitForDataJobsApiGetReqInterceptor(3);
- },
- after: () => {
- this.waitForDataJobsApiGetReqInterceptor();
-
- const page = this.getPage();
- page.waitForGridToLoad(null);
- page.waitForViewToRenderShort();
- }
- });
- }
-
- /**
- * ** Navigate to Manage Data Jobs.
- *
- * @return {DataJobsManagePage}
- */
- static navigateTo() {
- /**
- * @type {DataJobsManagePage}
- */
- const page = super.navigateTo('manage');
+ /**
+ * ** Returns instance of the page object.
+ *
+ * @returns {DataJobsManagePage}
+ */
+ static getPage() {
+ return new DataJobsManagePage();
+ }
+
+ /**
+ * ** Navigate to page with provided nav link id through side menu navigation, choose Team, and return instance of page object.
+ *
+ * @return {DataJobsManagePage}
+ */
+ static navigateWithSideMenu() {
+ return super.navigateWithSideMenu("navLinkManageDataJobs", "openManage", {
+ before: () => {
+ this.waitForApplicationBootstrap();
+ this.waitForDataJobsApiGetReqInterceptor(3);
+ },
+ after: () => {
+ this.waitForDataJobsApiGetReqInterceptor();
+
+ const page = this.getPage();
page.waitForGridToLoad(null);
page.waitForViewToRenderShort();
-
- return page;
- }
-
+ },
+ });
+ }
+
+ /**
+ * ** Navigate to Manage Data Jobs.
+ *
+ * @return {DataJobsManagePage}
+ */
+ static navigateTo() {
/**
- * ** Navigate to home page through URL and return instance of page object.
- * ** Do not wait for bootstrap and interceptors
- * @type {GetStartedPagePO}
+ * @type {DataJobsManagePage}
*/
- static navigateToNoBootstrap() {
- /**
- * @type {DataJobsManagePage}
- */
- const page = super.navigateToNoBootstrap('manage');
- page.waitForGridToLoad(null);
- return page;
- }
-
+ const page = super.navigateTo("manage");
+ page.waitForGridToLoad(null);
+ page.waitForViewToRenderShort();
+
+ return page;
+ }
+
+ /**
+ * ** Navigate to home page through URL and return instance of page object.
+ * ** Do not wait for bootstrap and interceptors
+ * @type {GetStartedPagePO}
+ */
+ static navigateToNoBootstrap() {
/**
- * ** Wait until Data grid is loaded.
- *
- * @param {string} contextSelector
- * @param {number} timeout
- * @returns {Cypress.Chainable}
+ * @type {DataJobsManagePage}
*/
- waitForGridToLoad(contextSelector, timeout = DataJobsBasePO.WAIT_SHORT_TASK) {
- return this._waitForGridToLoad('data-pipelines-manage-data-jobs', timeout);
- }
-
- getDataGrid() {
- return cy.get('[data-cy=data-pipelines-manage-grid]');
- }
-
- getDataGridNavigateBtn(team, job) {
- return cy.get('[data-cy=data-pipelines-manage-grid-details-link][data-job-params="' + team + ';' + job + '"]');
- }
-
- getDataGridRefreshButton() {
- return cy.get('[data-cy=data-pipelines-manage-refresh-btn]');
- }
-
- getExecuteNowGridButton() {
- return cy.get('[data-cy=data-pipelines-manage-grid-execute-btn]');
- }
-
- getJobStatus(jobName) {
- return this.getDataGridRowByName(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';
- }
-
- return 'not_deployed';
- });
- }
-
- // Actions
-
- executeDataJob(jobName) {
- this.selectRow(jobName);
-
- this.waitForClickThinkingTime();
-
- this.getExecuteNowGridButton().should('exist').click({ force: true });
-
- this.waitForViewToRenderShort();
-
- this.confirmInConfirmDialog(() => {
- this.waitForDataJobExecutionPostReqInterceptor();
- });
- }
-
- changeStatus(newStatus) {
- cy.get(`[data-cy=data-pipelines-job-${newStatus}-btn]`).should('exist').should('be.enabled').click({ force: true });
- }
-
- toggleJobStatus(jobName) {
- this.selectRow(jobName);
-
- this.getJobStatus(jobName).then((currentStatus) => {
- if (currentStatus === 'not_deployed') {
- throw new Error('Data job is not Deployed.');
- }
-
- const newStatus = currentStatus === 'enable' ? 'disable' : 'enable';
-
- cy.log(`Current status: ${currentStatus}, new status: ${newStatus}`);
-
- this.changeStatus(newStatus);
-
- this.confirmInConfirmDialog(() => {
- this.waitForDataJobDeploymentPatchReqInterceptor();
- });
-
- this.getToastTitle().should('exist').should('contain.text', 'Status update completed');
-
- this.getToastDismiss().should('exist').click({ force: true });
-
- this.waitForClickThinkingTime(); // Natural wait for User action
+ const page = super.navigateToNoBootstrap("manage");
+ page.waitForGridToLoad(null);
+ return page;
+ }
- this.refreshDataGrid();
+ /**
+ * ** Wait until Data grid is loaded.
+ *
+ * @param {string} contextSelector
+ * @param {number} timeout
+ * @returns {Cypress.Chainable}
+ */
+ waitForGridToLoad(contextSelector, timeout = DataJobsBasePO.WAIT_SHORT_TASK) {
+ return this._waitForGridToLoad("data-pipelines-manage-data-jobs", timeout);
+ }
+
+ getDataGrid() {
+ return cy.get("[data-cy=data-pipelines-manage-grid]");
+ }
+
+ getDataGridNavigateBtn(team, job) {
+ return cy.get(
+ '[data-cy=data-pipelines-manage-grid-details-link][data-job-params="' +
+ team +
+ ";" +
+ job +
+ '"]',
+ );
+ }
+
+ getDataGridRefreshButton() {
+ return cy.get("[data-cy=data-pipelines-manage-refresh-btn]");
+ }
+
+ getExecuteNowGridButton() {
+ return cy.get("[data-cy=data-pipelines-manage-grid-execute-btn]");
+ }
+
+ getJobStatus(jobName) {
+ return this.getDataGridRowByName(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";
+ }
+
+ return "not_deployed";
+ });
+ }
+
+ // Actions
+
+ executeDataJob(jobName) {
+ this.selectRow(jobName);
+
+ this.waitForClickThinkingTime();
+
+ this.getExecuteNowGridButton().should("exist").click({ force: true });
+
+ this.waitForViewToRenderShort();
+
+ this.confirmInConfirmDialog(() => {
+ this.waitForDataJobExecutionPostReqInterceptor();
+ });
+ }
+
+ changeStatus(newStatus) {
+ cy.get(`[data-cy=data-pipelines-job-${newStatus}-btn]`)
+ .should("exist")
+ .should("be.enabled")
+ .click({ force: true });
+ }
+
+ toggleJobStatus(jobName) {
+ this.selectRow(jobName);
+
+ this.getJobStatus(jobName).then((currentStatus) => {
+ if (currentStatus === "not_deployed") {
+ throw new Error("Data job is not Deployed.");
+ }
+
+ const newStatus = currentStatus === "enable" ? "disable" : "enable";
+
+ cy.log(`Current status: ${currentStatus}, new status: ${newStatus}`);
+
+ this.changeStatus(newStatus);
+
+ this.confirmInConfirmDialog(() => {
+ this.waitForDataJobDeploymentPatchReqInterceptor();
+ });
+
+ this.getToastTitle()
+ .should("exist")
+ .should("contain.text", "Status update completed");
+
+ this.getToastDismiss().should("exist").click({ force: true });
+
+ this.waitForClickThinkingTime(); // Natural wait for User action
+
+ this.refreshDataGrid();
- this.getJobStatus(jobName).then((changedStatus) => {
- expect(changedStatus).to.equal(newStatus);
- });
- });
- }
+ this.getJobStatus(jobName).then((changedStatus) => {
+ expect(changedStatus).to.equal(newStatus);
+ });
+ });
+ }
}
diff --git a/projects/frontend/data-pipelines/gui/e2e/support/pages/manage/data-jobs/details/data-job-details.po.js b/projects/frontend/data-pipelines/gui/e2e/support/pages/manage/data-jobs/details/data-job-details.po.js
index 0ed68a2fc9..8fb42e0ae0 100644
--- a/projects/frontend/data-pipelines/gui/e2e/support/pages/manage/data-jobs/details/data-job-details.po.js
+++ b/projects/frontend/data-pipelines/gui/e2e/support/pages/manage/data-jobs/details/data-job-details.po.js
@@ -5,257 +5,294 @@
///
-import { DataJobDetailsBasePO } from '../../../base/data-pipelines/data-job-details-base.po';
+import { DataJobDetailsBasePO } from "../../../base/data-pipelines/data-job-details-base.po";
export class DataJobManageDetailsPage extends DataJobDetailsBasePO {
- /**
- * ** Returns instance of the page object.
- *
- * @returns {DataJobManageDetailsPage}
- */
- static getPage() {
- return new DataJobManageDetailsPage();
+ /**
+ * ** Returns instance of the page object.
+ *
+ * @returns {DataJobManageDetailsPage}
+ */
+ static getPage() {
+ return new DataJobManageDetailsPage();
+ }
+
+ /**
+ * @inheritDoc
+ * @return {DataJobManageDetailsPage}
+ */
+ static navigateTo(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 + "]");
+ }
+
+ // Description methods
+
+ getDescription() {
+ 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",
+ );
+ }
+
+ getDescriptionEditTextarea() {
+ 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)",
+ );
+ }
+
+ openDescription() {
+ this.getDescriptionEditButton().click({ force: true });
+ }
+
+ enterDescriptionDetails(description) {
+ this.getDescriptionEditTextarea().clear().type(description);
+ }
+
+ saveDescription() {
+ this.getDescriptionSaveButton().click({ force: true });
+
+ this.waitForDataJobPutReqInterceptor();
+ }
+
+ /**
+ * ** Format ISO DateTime to Data job executions timeline format.
+ *
+ * e.g.
+ * '2023-03-27T10:25:24.960717Z' -> 'Mar 27, 2023, 10:25 AM UTC'
+ *
+ * @param {string} isoDate
+ */
+ formatDateTimeFromISOToExecutionsTimeline(isoDate) {
+ const dateTimeChunks = isoDate.replace(/(\..*)?Z$/, "").split("T");
+ const dateChunk = dateTimeChunks[0];
+ const timeChunk = dateTimeChunks[1];
+
+ return `${this._formatDateFromISOToExecutionsTimeline(dateChunk)}, ${this._formatTimeFromISOToExecutionsTimeline(timeChunk)} UTC`;
+ }
+
+ // Schedule methods
+
+ getSchedule() {
+ 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",
+ );
+ }
+
+ getStatusSaveButton() {
+ return cy.get(
+ "[data-cy=data-pipelines-data-job-details-status] button:contains(Save)",
+ );
+ }
+
+ // Executions Timeline
+
+ getExecutionsSteps() {
+ return cy.get(".clr-timeline-step");
+ }
+
+ getExecutionStepStartedTile(stepSelector) {
+ return cy
+ .get(stepSelector)
+ .should("exist")
+ .scrollIntoView()
+ .find("[data-cy=data-pipelines-executions-timeline-started]")
+ .invoke("attr", "title");
+ }
+
+ getExecutionStepEndedTile(stepSelector) {
+ return cy
+ .get(stepSelector)
+ .should("exist")
+ .find("[data-cy=data-pipelines-executions-timeline-ended]")
+ .invoke("attr", "title");
+ }
+
+ getExecutionStepManualTriggerer(stepSelector) {
+ return cy
+ .get(stepSelector)
+ .find("[data-cy=data-pipelines-executions-timeline-manual-start]");
+ }
+
+ getExecutionStepStatusIcon(stepSelector, status) {
+ const STATUS_ICON_MAP = {};
+ STATUS_ICON_MAP["SUBMITTED"] = "hourglass";
+ STATUS_ICON_MAP["RUNNING"] = "play";
+ STATUS_ICON_MAP["SUCCEEDED"] = "success-standard";
+ STATUS_ICON_MAP["CANCELLED"] = "times-circle";
+ STATUS_ICON_MAP["SKIPPED"] = "circle-arrow";
+ STATUS_ICON_MAP["USER_ERROR"] = "error-standard";
+ STATUS_ICON_MAP["PLATFORM_ERROR"] = "error-standard";
+
+ if (status === "RUNNING") {
+ return cy.get(stepSelector).find(`clr-spinner[aria-label='In progress']`);
}
- /**
- * @inheritDoc
- * @return {DataJobManageDetailsPage}
- */
- static navigateTo(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 + ']');
- }
-
- // Description methods
-
- getDescription() {
- 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');
- }
-
- getDescriptionEditTextarea() {
- 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)');
- }
-
- openDescription() {
- this.getDescriptionEditButton().click({ force: true });
- }
-
- enterDescriptionDetails(description) {
- this.getDescriptionEditTextarea().clear().type(description);
- }
-
- saveDescription() {
- this.getDescriptionSaveButton().click({ force: true });
-
- this.waitForDataJobPutReqInterceptor();
- }
+ return cy.get(stepSelector).find(`[shape=${STATUS_ICON_MAP[status]}]`);
+ }
- /**
- * ** Format ISO DateTime to Data job executions timeline format.
- *
- * e.g.
- * '2023-03-27T10:25:24.960717Z' -> 'Mar 27, 2023, 10:25 AM UTC'
- *
- * @param {string} isoDate
- */
- formatDateTimeFromISOToExecutionsTimeline(isoDate) {
- const dateTimeChunks = isoDate.replace(/(\..*)?Z$/, '').split('T');
- const dateChunk = dateTimeChunks[0];
- const timeChunk = dateTimeChunks[1];
-
- return `${this._formatDateFromISOToExecutionsTimeline(dateChunk)}, ${this._formatTimeFromISOToExecutionsTimeline(timeChunk)} UTC`;
- }
+ // Actions
- // Schedule methods
+ changeStatus(currentStatus) {
+ const newStatus =
+ currentStatus.trim().toLowerCase() === "enabled" ? "disable" : "enable";
- 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-status-${newStatus}]`)
+ .should("exist")
+ .check({ force: true });
+ }
- // Disable/Enable methods
+ toggleJobStatus() {
+ cy.get("[data-cy=data-pipelines-job-details-status]")
+ .invoke("text")
+ .then((jobStatus) => {
+ this.getStatusEditButton().scrollIntoView().click({ force: true });
- getStatusEditButton() {
- 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)');
- }
+ this.changeStatus(jobStatus);
- // Executions Timeline
+ this.waitForClickThinkingTime();
- getExecutionsSteps() {
- return cy.get('.clr-timeline-step');
- }
+ this.getStatusSaveButton().scrollIntoView().click({ force: true });
- getExecutionStepStartedTile(stepSelector) {
- return cy.get(stepSelector).should('exist').scrollIntoView().find('[data-cy=data-pipelines-executions-timeline-started]').invoke('attr', 'title');
- }
+ let newStatus = jobStatus === "Enabled" ? "Disabled" : "Enabled";
- getExecutionStepEndedTile(stepSelector) {
- return cy.get(stepSelector).should('exist').find('[data-cy=data-pipelines-executions-timeline-ended]').invoke('attr', 'title');
- }
+ this.waitForDataJobDeploymentPatchReqInterceptor();
- getExecutionStepManualTriggerer(stepSelector) {
- return cy.get(stepSelector).find('[data-cy=data-pipelines-executions-timeline-manual-start]');
- }
+ this.getToastTitle()
+ .should("exist")
+ .should("contain.text", "Status update completed");
- getExecutionStepStatusIcon(stepSelector, status) {
- const STATUS_ICON_MAP = {};
- STATUS_ICON_MAP['SUBMITTED'] = 'hourglass';
- STATUS_ICON_MAP['RUNNING'] = 'play';
- STATUS_ICON_MAP['SUCCEEDED'] = 'success-standard';
- STATUS_ICON_MAP['CANCELLED'] = 'times-circle';
- STATUS_ICON_MAP['SKIPPED'] = 'circle-arrow';
- STATUS_ICON_MAP['USER_ERROR'] = 'error-standard';
- STATUS_ICON_MAP['PLATFORM_ERROR'] = 'error-standard';
-
- if (status === 'RUNNING') {
- return cy.get(stepSelector).find(`clr-spinner[aria-label='In progress']`);
- }
-
- return cy.get(stepSelector).find(`[shape=${STATUS_ICON_MAP[status]}]`);
- }
+ this.waitForActionThinkingTime(); // Natural wait for User action
- // Actions
+ this.getToastDismiss().should("exist").click({ force: true });
- changeStatus(currentStatus) {
- const newStatus = currentStatus.trim().toLowerCase() === 'enabled' ? 'disable' : 'enable';
+ cy.get("[data-cy=data-pipelines-job-details-status]")
+ .scrollIntoView()
+ .should("have.text", newStatus);
+ });
+ }
- return cy.get(`[data-cy=data-pipelines-data-job-details-status-${newStatus}]`).should('exist').check({ force: true });
+ /**
+ * ** Format Date chunk to Data job Executions timeline format.
+ *
+ * e.g.
+ * '2023-03-27' -> 'Mar 27, 2023'
+ *
+ * @param {string} dateChunk
+ * @return {string}
+ * @private
+ */
+ _formatDateFromISOToExecutionsTimeline(dateChunk) {
+ if (!dateChunk) {
+ return "";
}
- toggleJobStatus() {
- cy.get('[data-cy=data-pipelines-job-details-status]')
- .invoke('text')
- .then((jobStatus) => {
- this.getStatusEditButton().scrollIntoView().click({ force: true });
-
- this.changeStatus(jobStatus);
-
- this.waitForClickThinkingTime();
-
- this.getStatusSaveButton().scrollIntoView().click({ force: true });
-
- let newStatus = jobStatus === 'Enabled' ? 'Disabled' : 'Enabled';
-
- this.waitForDataJobDeploymentPatchReqInterceptor();
-
- this.getToastTitle().should('exist').should('contain.text', 'Status update completed');
-
- this.waitForActionThinkingTime(); // Natural wait for User action
-
- this.getToastDismiss().should('exist').click({ force: true });
-
- cy.get('[data-cy=data-pipelines-job-details-status]').scrollIntoView().should('have.text', newStatus);
- });
+ const dateChunks = dateChunk.split("-");
+ const year = dateChunks[0];
+ const month = dateChunks[1];
+ const day = parseInt(dateChunks[2], 10);
+
+ const dayMonth = `${day}, ${year}`;
+
+ let monthAbbreviation;
+
+ switch (month) {
+ case "01":
+ monthAbbreviation = "Jan";
+ break;
+ case "02":
+ monthAbbreviation = "Feb";
+ break;
+ case "03":
+ monthAbbreviation = "Mar";
+ break;
+ case "04":
+ monthAbbreviation = "Apr";
+ break;
+ case "05":
+ monthAbbreviation = "May";
+ break;
+ case "06":
+ monthAbbreviation = "Jun";
+ break;
+ case "07":
+ monthAbbreviation = "Jul";
+ break;
+ case "08":
+ monthAbbreviation = "Aug";
+ break;
+ case "09":
+ monthAbbreviation = "Sep";
+ break;
+ case "10":
+ monthAbbreviation = "Oct";
+ break;
+ case "11":
+ monthAbbreviation = "Nov";
+ break;
+ case "12":
+ monthAbbreviation = "Dec";
+ break;
+ default:
+ monthAbbreviation = "";
}
- /**
- * ** Format Date chunk to Data job Executions timeline format.
- *
- * e.g.
- * '2023-03-27' -> 'Mar 27, 2023'
- *
- * @param {string} dateChunk
- * @return {string}
- * @private
- */
- _formatDateFromISOToExecutionsTimeline(dateChunk) {
- if (!dateChunk) {
- return '';
- }
-
- const dateChunks = dateChunk.split('-');
- const year = dateChunks[0];
- const month = dateChunks[1];
- const day = parseInt(dateChunks[2], 10);
-
- const dayMonth = `${day}, ${year}`;
-
- let monthAbbreviation;
-
- switch (month) {
- case '01':
- monthAbbreviation = 'Jan';
- break;
- case '02':
- monthAbbreviation = 'Feb';
- break;
- case '03':
- monthAbbreviation = 'Mar';
- break;
- case '04':
- monthAbbreviation = 'Apr';
- break;
- case '05':
- monthAbbreviation = 'May';
- break;
- case '06':
- monthAbbreviation = 'Jun';
- break;
- case '07':
- monthAbbreviation = 'Jul';
- break;
- case '08':
- monthAbbreviation = 'Aug';
- break;
- case '09':
- monthAbbreviation = 'Sep';
- break;
- case '10':
- monthAbbreviation = 'Oct';
- break;
- case '11':
- monthAbbreviation = 'Nov';
- break;
- case '12':
- monthAbbreviation = 'Dec';
- break;
- default:
- monthAbbreviation = '';
- }
-
- return `${monthAbbreviation} ${dayMonth}`;
+ return `${monthAbbreviation} ${dayMonth}`;
+ }
+
+ /**
+ * ** Format Time chunk to Data job Executions timeline format.
+ *
+ * e.g.
+ * '10:25:24' -> '10:25 AM'
+ *
+ * @param {string} timeChunk
+ * @return {string}
+ * @private
+ */
+ _formatTimeFromISOToExecutionsTimeline(timeChunk) {
+ if (!timeChunk) {
+ return "";
}
- /**
- * ** Format Time chunk to Data job Executions timeline format.
- *
- * e.g.
- * '10:25:24' -> '10:25 AM'
- *
- * @param {string} timeChunk
- * @return {string}
- * @private
- */
- _formatTimeFromISOToExecutionsTimeline(timeChunk) {
- if (!timeChunk) {
- return '';
- }
-
- const timeChunks = timeChunk.split(':');
- const hour = parseInt(timeChunks[0], 10);
- const minute = parseInt(timeChunks[1], 10);
- const beforeOrAfter = hour >= 12 ? 'PM' : 'AM';
- const hourNormalizedTo12Hours = hour > 12 ? hour % 12 : hour === 0 ? 12 : hour;
- const hourNormalizedToString = hourNormalizedTo12Hours < 10 ? `0${hourNormalizedTo12Hours}` : `${hourNormalizedTo12Hours}`;
- const minuteNormalizedToString = minute < 10 ? `0${minute}` : `${minute}`;
-
- return `${hourNormalizedToString}:${minuteNormalizedToString} ${beforeOrAfter}`;
- }
+ const timeChunks = timeChunk.split(":");
+ const hour = parseInt(timeChunks[0], 10);
+ const minute = parseInt(timeChunks[1], 10);
+ const beforeOrAfter = hour >= 12 ? "PM" : "AM";
+ const hourNormalizedTo12Hours =
+ hour > 12 ? hour % 12 : hour === 0 ? 12 : hour;
+ const hourNormalizedToString =
+ hourNormalizedTo12Hours < 10
+ ? `0${hourNormalizedTo12Hours}`
+ : `${hourNormalizedTo12Hours}`;
+ const minuteNormalizedToString = minute < 10 ? `0${minute}` : `${minute}`;
+
+ return `${hourNormalizedToString}:${minuteNormalizedToString} ${beforeOrAfter}`;
+ }
}
diff --git a/projects/frontend/data-pipelines/gui/e2e/support/pages/manage/data-jobs/executions/data-job-executions.po.js b/projects/frontend/data-pipelines/gui/e2e/support/pages/manage/data-jobs/executions/data-job-executions.po.js
index fdabfcc458..2f3d031760 100644
--- a/projects/frontend/data-pipelines/gui/e2e/support/pages/manage/data-jobs/executions/data-job-executions.po.js
+++ b/projects/frontend/data-pipelines/gui/e2e/support/pages/manage/data-jobs/executions/data-job-executions.po.js
@@ -5,658 +5,778 @@
///
-import { DataJobBasePO } from '../../../base/data-pipelines/data-job-base.po';
-import { DataJobsBasePO } from '../../../base/data-pipelines/data-jobs-base.po';
+import { DataJobBasePO } from "../../../base/data-pipelines/data-job-base.po";
+import { DataJobsBasePO } from "../../../base/data-pipelines/data-jobs-base.po";
export class DataJobManageExecutionsPage extends DataJobBasePO {
+ /**
+ * ** Returns instance of the page object.
+ *
+ * @returns {DataJobManageExecutionsPage}
+ */
+ static getPage() {
+ return new DataJobManageExecutionsPage();
+ }
+
+ /**
+ * @inheritDoc
+ * @return {DataJobManageExecutionsPage}
+ */
+ static navigateTo(teamName, jobName) {
/**
- * ** Returns instance of the page object.
- *
- * @returns {DataJobManageExecutionsPage}
+ * @type {DataJobManageExecutionsPage}
*/
- static getPage() {
- return new DataJobManageExecutionsPage();
- }
-
- /**
- * @inheritDoc
- * @return {DataJobManageExecutionsPage}
- */
- static navigateTo(teamName, jobName) {
+ const page = super.navigateTo("manage", teamName, jobName, "executions");
+ page.waitForGridToLoad(null);
+ page.waitForViewToRenderShort();
+
+ return page;
+ }
+
+ /**
+ * ** Navigate to Data Job executions page with provided URL.
+ *
+ * @param {string} url
+ * @return {DataJobManageExecutionsPage}
+ */
+ static navigateToExecutionsWithUrl(url) {
+ const page = this.navigateToDataJobUrl(url, 3);
+
+ page.waitForGridToLoad(null);
+ page.waitForViewToRenderShort();
+
+ return page;
+ }
+
+ /* Utils */
+
+ /**
+ * ** Converts from view time to seconds.
+ *
+ * @example
+ *
+ * - val=1m 34s
+ * - val=45s
+ *
+ * @return {number}
+ */
+ convertStringContentToSeconds(val) {
+ const params = val.trim().split(" ");
+
+ if (params.length === 2) {
+ 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);
+ }
+ }
+
+ /* Selectors */
+
+ /**
+ * ** Wait until Data grid is loaded.
+ *
+ * @param {string} contextSelector
+ * @param {number} timeout
+ * @returns {Cypress.Chainable}
+ */
+ waitForGridToLoad(contextSelector, timeout = DataJobsBasePO.WAIT_SHORT_TASK) {
+ return this._waitForGridToLoad(
+ "data-pipelines-data-job-executions",
+ timeout,
+ );
+ }
+
+ // General
+
+ getExecRefreshBtn() {
+ return cy.get("[data-cy=data-pipelines-job-executions-refresh-btn");
+ }
+
+ getExecLoadingSpinner() {
+ return cy.get("[data-cy=data-pipelines-job-executions-loading-spinner]");
+ }
+
+ // Charts
+
+ getStatusChart() {
+ return cy.get("[data-cy=data-pipelines-job-executions-status-chart]");
+ }
+
+ getDurationChart() {
+ return cy.get("[data-cy=data-pipelines-job-executions-duration-chart]");
+ }
+
+ getTimePeriod() {
+ return cy.get("[data-cy=data-pipelines-job-executions-time-period]");
+ }
+
+ // DataGrid
+
+ getDataGrid() {
+ return cy.get("[data-cy=data-pipelines-job-executions-datagrid]", {
+ timeout: DataJobManageExecutionsPage.WAIT_SHORT_TASK,
+ });
+ }
+
+ getDataGridPopupFilter() {
+ return cy.get(".datagrid-filter.clr-popover-content");
+ }
+
+ getDataGridInputFilter() {
+ return this.getDataGridPopupFilter().should("exist").find("input");
+ }
+
+ getDataGridPopupFilterCloseBtn() {
+ return this.getDataGridPopupFilter().should("exist").find(".close");
+ }
+
+ getDataGridSpinner() {
+ return this.getDataGrid().should("exist").find(".datagrid-spinner");
+ }
+
+ // Header
+
+ // status
+ getDataGridExecStatusHeader() {
+ return this.getDataGrid()
+ .should("exist")
+ .find("[data-cy=data-pipelines-job-executions-status-header]");
+ }
+
+ getDataGridExecStatusFilterOpenerBtn() {
+ return this.getDataGridExecStatusHeader()
+ .should("exist")
+ .find(".datagrid-filter-toggle");
+ }
+
+ getDataGridExecStatusFilters() {
+ return this.getDataGridPopupFilter()
+ .should("exist")
+ .find("[data-cy=data-pipelines-job-executions-status-filters]");
+ }
+
+ getDataGridExecStatusSortBtn() {
+ return this.getDataGridExecStatusHeader()
+ .should("exist")
+ .find(".datagrid-column-title");
+ }
+
+ /**
+ * ** Get status filter label
+ *
+ * @param {'succeeded'|'platform_error'|'user_error'|'running'|'submitted'|'skipped'|'cancelled'} status
+ * @return {Cypress.Chainable>}
+ */
+ getDataGridExecStatusFilterLabel(status) {
+ return cy.get(`[data-cy=dp-job-executions-status-filter-label-${status}]`);
+ }
+
+ /**
+ * ** Get status filter checkbox
+ *
+ * @param {'succeeded'|'platform_error'|'user_error'|'running'|'submitted'|'skipped'|'cancelled'} status
+ * @return {Cypress.Chainable>}
+ */
+ getDataGridExecStatusFilterCheckbox(status) {
+ return cy.get(
+ `[data-cy=dp-job-executions-status-filter-checkbox-${status}]`,
+ );
+ }
+
+ getDataGridExecStatusFilterCheckboxesStatuses() {
+ return cy
+ .get("[data-cy=dp-job-executions-status-filter-checkbox] input")
+ .then(($checkboxes) => {
+ return cy.wrap(
+ Array.from($checkboxes).map((checkbox) => {
+ const key = checkbox.getAttribute("data-cy").split("-").pop();
+ const value = checkbox.checked;
+
+ return [key, value];
+ }),
+ );
+ });
+ }
+
+ // type
+ getDataGridExecTypeHeader() {
+ return this.getDataGrid()
+ .should("exist")
+ .find("[data-cy=data-pipelines-job-executions-type-header]");
+ }
+
+ getDataGridExecTypeFilterOpenerBtn() {
+ return this.getDataGridExecTypeHeader()
+ .should("exist")
+ .find(".datagrid-filter-toggle");
+ }
+
+ getDataGridExecTypeSortBtn() {
+ return this.getDataGridExecTypeHeader()
+ .should("exist")
+ .find(".datagrid-column-title");
+ }
+
+ /**
+ * ** Get type filter label
+ *
+ * @param {'manual'|'scheduled'} type
+ * @return {Cypress.Chainable>}
+ */
+ getDataGridExecTypeFilterLabel(type) {
+ return cy.get(`[data-cy=dp-job-executions-type-filter-label-${type}]`);
+ }
+
+ /**
+ * ** Get type filter checkbox
+ *
+ * @param {'manual'|'scheduled'} type
+ * @return {Cypress.Chainable>}
+ */
+ getDataGridExecTypeFilterCheckbox(type) {
+ return cy.get(`[data-cy=dp-job-executions-type-filter-checkbox-${type}]`);
+ }
+
+ getDataGridExecTypeFilterCheckboxesStatuses() {
+ return cy
+ .get("[data-cy=dp-job-executions-type-filter-checkbox] input")
+ .then(($checkboxes) => {
+ return cy.wrap(
+ Array.from($checkboxes).map((checkbox) => {
+ const key = checkbox.getAttribute("data-cy").split("-").pop();
+ const value = checkbox.checked;
+
+ return [key, value];
+ }),
+ );
+ });
+ }
+
+ // duration
+ getDataGridExecDurationHeader() {
+ return this.getDataGrid()
+ .should("exist")
+ .find("[data-cy=data-pipelines-job-executions-duration-header]");
+ }
+
+ getDataGridExecDurationFilterOpenerBtn() {
+ return this.getDataGridExecDurationHeader()
+ .should("exist")
+ .find(".datagrid-filter-toggle");
+ }
+
+ getDataGridExecDurationSortBtn() {
+ return this.getDataGridExecDurationHeader()
+ .should("exist")
+ .find(".datagrid-column-title");
+ }
+
+ // exec start
+ getDataGridExecStartHeader() {
+ return this.getDataGrid()
+ .should("exist")
+ .find("[data-cy=data-pipelines-job-executions-start-header]");
+ }
+
+ getDataGridExecStartFilterOpenerBtn() {
+ return this.getDataGridExecStartHeader()
+ .should("exist")
+ .find(".datagrid-filter-toggle");
+ }
+
+ getDataGridExecStartSortBtn() {
+ return this.getDataGridExecStartHeader()
+ .should("exist")
+ .find(".datagrid-column-title");
+ }
+
+ // exec end
+ getDataGridExecEndHeader() {
+ return this.getDataGrid()
+ .should("exist")
+ .find("[data-cy=data-pipelines-job-executions-end-header]");
+ }
+
+ getDataGridExecEndFilterOpenerBtn() {
+ return this.getDataGridExecEndHeader()
+ .should("exist")
+ .find(".datagrid-filter-toggle");
+ }
+
+ getDataGridExecEndSortBtn() {
+ return this.getDataGridExecEndHeader()
+ .should("exist")
+ .find(".datagrid-column-title");
+ }
+
+ // id
+ getDataGridExecIDHeader() {
+ return this.getDataGrid()
+ .should("exist")
+ .find("[data-cy=data-pipelines-job-executions-id-header]");
+ }
+
+ getDataGridExecIDFilterOpenerBtn() {
+ return this.getDataGridExecIDHeader()
+ .should("exist")
+ .find(".datagrid-filter-toggle");
+ }
+
+ getDataGridExecIDSortBtn() {
+ return this.getDataGridExecIDHeader()
+ .should("exist")
+ .find(".datagrid-column-title");
+ }
+
+ // version
+ getDataGridExecVersionHeader() {
+ return this.getDataGrid()
+ .should("exist")
+ .find("[data-cy=data-pipelines-job-executions-version-header]");
+ }
+
+ getDataGridExecVersionFilterOpenerBtn() {
+ return this.getDataGridExecVersionHeader()
+ .should("exist")
+ .find(".datagrid-filter-toggle");
+ }
+
+ getDataGridExecVersionSortBtn() {
+ return this.getDataGridExecVersionHeader()
+ .should("exist")
+ .find(".datagrid-column-title");
+ }
+
+ // Rows and Cells
+
+ getDataGridRows() {
+ return this.getDataGrid().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]);
+ }
+
+ getDataGridCells(rowIndex) {
+ return this.getDataGridRow(rowIndex)
+ .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]);
+ }
+
+ return this.getDataGridRows()
+ .should("have.length.gte", 0)
+ .then(($rows) => {
+ return $rows.reduce((accumulator, row) => {
+ const _cells = Array.from(
+ row.querySelectorAll("clr-dg-cell.datagrid-cell"),
+ );
+
+ if (_cells[cellIndex - 1]) {
+ accumulator.push(_cells[cellIndex - 1]);
+ }
+
+ return accumulator;
+ }, []);
+ });
+ }
+
+ getDataGridCellByIdentifier(rowIndex, identifier) {
+ return this.getDataGridRow(rowIndex).should("exist").find(identifier);
+ }
+
+ getDataGridCellsByIdentifier(identifier) {
+ return this.getDataGrid().should("exist").find(identifier);
+ }
+
+ // type
+ getDataGridExecTypeCell(rowIndex) {
+ return this.getDataGridCellByIdentifier(
+ rowIndex,
+ "[data-cy=data-pipelines-job-executions-type-cell]",
+ );
+ }
+
+ /**
+ * ** Get containers in cells for given type.
+ *
+ * @param {'manual'|'scheduled'} type
+ * @return {Cypress.Chainable>}
+ */
+ getDataGridExecTypeContainers(type) {
+ return this.getDataGrid()
+ .should("exist")
+ .then(($gridContainer) => {
/**
- * @type {DataJobManageExecutionsPage}
+ * @type {JQuery}
*/
- const page = super.navigateTo('manage', teamName, jobName, 'executions');
- page.waitForGridToLoad(null);
- page.waitForViewToRenderShort();
-
- return page;
- }
-
- /**
- * ** Navigate to Data Job executions page with provided URL.
- *
- * @param {string} url
- * @return {DataJobManageExecutionsPage}
- */
- static navigateToExecutionsWithUrl(url) {
- const page = this.navigateToDataJobUrl(url, 3);
-
- page.waitForGridToLoad(null);
- page.waitForViewToRenderShort();
-
- return page;
- }
-
- /* Utils */
-
- /**
- * ** Converts from view time to seconds.
- *
- * @example
- *
- * - val=1m 34s
- * - val=45s
- *
- * @return {number}
- */
- convertStringContentToSeconds(val) {
- const params = val.trim().split(' ');
-
- if (params.length === 2) {
- 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);
+ const $containers = $gridContainer.find(
+ "[data-cy=data-pipelines-job-executions-type-container]",
+ );
+
+ return cy.wrap($containers.length === 0 ? [] : $containers);
+ })
+ .then(($containers) => {
+ return cy.wrap(
+ Array.from($containers)
+ .map((container) => container.getAttribute("title").toLowerCase())
+ .filter((title) => new RegExp(`^${type}`).test(title)),
+ );
+ });
+ }
+
+ // getDataGridExecStatusFilterCheckboxesStatuses() {
+ // return cy.get('[data-cy=dp-job-executions-status-filter-checkbox] input')
+ // .then(($checkboxes) => {
+ // return cy.wrap(Array.from($checkboxes).map((checkbox) => {
+ // const key = checkbox.getAttribute('data-cy').split('-').pop();
+ // const value = checkbox.checked;
+ //
+ // return [key, value];
+ // }));
+ // });
+ // }
+
+ // duration
+ getDataGridExecDurationCell(rowIndex) {
+ return this.getDataGridCellByIdentifier(
+ rowIndex,
+ "[data-cy=data-pipelines-job-executions-duration-cell]",
+ );
+ }
+
+ // exec start
+ getDataGridExecStartCell(rowIndex) {
+ return this.getDataGridCellByIdentifier(
+ rowIndex,
+ "[data-cy=data-pipelines-job-executions-start-cell]",
+ );
+ }
+
+ getDataGridExecStartCells() {
+ return this.getDataGridCellsByIdentifier(
+ "[data-cy=data-pipelines-job-executions-start-cell]",
+ );
+ }
+
+ generateExecStartFilterValue() {
+ return this.getDataGridExecStartCells().then(($cells) => {
+ const pmCells = Array.from($cells).map((cell) =>
+ /PM$/.test(`${cell.innerText?.trim()}`),
+ );
+ if (pmCells.length >= 2) {
+ return cy.wrap("PM");
+ }
+
+ const amCells = Array.from($cells).map((cell) =>
+ /AM$/.test(`${cell.innerText?.trim()}`),
+ );
+ if (amCells.length >= 2) {
+ return cy.wrap("AM");
+ }
+
+ throw new Error("Unhandled use case in test scenarios");
+ });
+ }
+
+ // exec end
+ getDataGridExecEndCell(rowIndex) {
+ return this.getDataGridCellByIdentifier(
+ rowIndex,
+ "[data-cy=data-pipelines-job-executions-end-cell]",
+ );
+ }
+
+ getDataGridExecEndCells() {
+ return this.getDataGridCellsByIdentifier(
+ "[data-cy=data-pipelines-job-executions-end-cell]",
+ );
+ }
+
+ generateExecEndFilterValue() {
+ return this.getDataGridExecEndCells().then(($cells) => {
+ const pmCells = Array.from($cells).map((cell) =>
+ /PM$/.test(`${cell.innerText?.trim()}`),
+ );
+
+ if (pmCells.length > 0) {
+ return cy.wrap("PM");
+ }
+
+ return cy.wrap("AM");
+ });
+ }
+
+ // id
+ getDataGridExecIDCell(rowIndex) {
+ return this.getDataGridCellByIdentifier(
+ rowIndex,
+ "[data-cy=data-pipelines-job-executions-id-cell]",
+ );
+ }
+
+ getDataGridExecIDCells() {
+ return this.getDataGridCellsByIdentifier(
+ "[data-cy=data-pipelines-job-executions-id-cell]",
+ );
+ }
+
+ // exec version
+ getDataGridExecVersionCell(rowIndex) {
+ return this.getDataGridCellByIdentifier(
+ rowIndex,
+ "[data-cy=data-pipelines-job-executions-job-version-cell]",
+ );
+ }
+
+ getDataGridExecVersionCells() {
+ return this.getDataGridCellsByIdentifier(
+ "[data-cy=data-pipelines-job-executions-job-version-cell]",
+ );
+ }
+
+ // Pagination
+
+ getDataGridPagination() {
+ return this.getDataGrid()
+ .should("exist")
+ .find("[data-cy=data-pipelines-job-executions-datagrid-pagination]");
+ }
+
+ /* Actions */
+
+ // General
+
+ refreshExecData() {
+ this.getExecRefreshBtn().should("exist").click({ force: true });
+ }
+
+ // DataGrid
+
+ typeToTextFilterInput(value) {
+ this.getDataGridInputFilter().should("exist").type(value);
+
+ this.waitForViewToRender();
+ }
+
+ clearTextFilterInput() {
+ this.getDataGridInputFilter().should("exist").clear({ force: true });
+
+ this.waitForViewToRender();
+ }
+
+ closeFilter() {
+ this.getDataGridPopupFilterCloseBtn()
+ .should("exist")
+ .click({ force: true });
+
+ this.waitForViewToRenderShort();
+ }
+
+ // Header
+
+ // status
+ /**
+ * ** Open status filter.
+ */
+ openStatusFilter() {
+ this.getDataGridExecStatusFilterOpenerBtn()
+ .should("exist")
+ .click({ force: true });
+
+ this.waitForViewToRenderShort();
+ }
+
+ /**
+ * ** Choose filter by some status.
+ *
+ * @param {'succeeded'|'platform_error'|'user_error'|'running'|'submitted'|'skipped'|'cancelled'} status
+ */
+ filterByStatus(status) {
+ this.getDataGridExecStatusFilterCheckbox(status)
+ .should("exist")
+ .as("checkbox")
+ .invoke("is", ":checked")
+ .then((checked) => {
+ if (!checked) {
+ this.getDataGridExecStatusFilterLabel(status)
+ .should("exist")
+ .click({ force: true });
}
- }
-
- /* Selectors */
-
- /**
- * ** Wait until Data grid is loaded.
- *
- * @param {string} contextSelector
- * @param {number} timeout
- * @returns {Cypress.Chainable}
- */
- waitForGridToLoad(contextSelector, timeout = DataJobsBasePO.WAIT_SHORT_TASK) {
- return this._waitForGridToLoad('data-pipelines-data-job-executions', timeout);
- }
-
- // General
-
- getExecRefreshBtn() {
- return cy.get('[data-cy=data-pipelines-job-executions-refresh-btn');
- }
-
- getExecLoadingSpinner() {
- return cy.get('[data-cy=data-pipelines-job-executions-loading-spinner]');
- }
-
- // Charts
-
- getStatusChart() {
- return cy.get('[data-cy=data-pipelines-job-executions-status-chart]');
- }
-
- getDurationChart() {
- return cy.get('[data-cy=data-pipelines-job-executions-duration-chart]');
- }
-
- getTimePeriod() {
- return cy.get('[data-cy=data-pipelines-job-executions-time-period]');
- }
-
- // DataGrid
-
- getDataGrid() {
- return cy.get('[data-cy=data-pipelines-job-executions-datagrid]', {
- timeout: DataJobManageExecutionsPage.WAIT_SHORT_TASK
- });
- }
-
- getDataGridPopupFilter() {
- return cy.get('.datagrid-filter.clr-popover-content');
- }
-
- getDataGridInputFilter() {
- return this.getDataGridPopupFilter().should('exist').find('input');
- }
-
- getDataGridPopupFilterCloseBtn() {
- return this.getDataGridPopupFilter().should('exist').find('.close');
- }
-
- getDataGridSpinner() {
- return this.getDataGrid().should('exist').find('.datagrid-spinner');
- }
-
- // Header
-
- // status
- getDataGridExecStatusHeader() {
- return this.getDataGrid().should('exist').find('[data-cy=data-pipelines-job-executions-status-header]');
- }
-
- getDataGridExecStatusFilterOpenerBtn() {
- return this.getDataGridExecStatusHeader().should('exist').find('.datagrid-filter-toggle');
- }
-
- getDataGridExecStatusFilters() {
- return this.getDataGridPopupFilter().should('exist').find('[data-cy=data-pipelines-job-executions-status-filters]');
- }
-
- getDataGridExecStatusSortBtn() {
- return this.getDataGridExecStatusHeader().should('exist').find('.datagrid-column-title');
- }
-
- /**
- * ** Get status filter label
- *
- * @param {'succeeded'|'platform_error'|'user_error'|'running'|'submitted'|'skipped'|'cancelled'} status
- * @return {Cypress.Chainable>}
- */
- getDataGridExecStatusFilterLabel(status) {
- return cy.get(`[data-cy=dp-job-executions-status-filter-label-${status}]`);
- }
-
- /**
- * ** Get status filter checkbox
- *
- * @param {'succeeded'|'platform_error'|'user_error'|'running'|'submitted'|'skipped'|'cancelled'} status
- * @return {Cypress.Chainable>}
- */
- getDataGridExecStatusFilterCheckbox(status) {
- return cy.get(`[data-cy=dp-job-executions-status-filter-checkbox-${status}]`);
- }
-
- getDataGridExecStatusFilterCheckboxesStatuses() {
- return cy.get('[data-cy=dp-job-executions-status-filter-checkbox] input').then(($checkboxes) => {
- return cy.wrap(
- Array.from($checkboxes).map((checkbox) => {
- const key = checkbox.getAttribute('data-cy').split('-').pop();
- const value = checkbox.checked;
-
- return [key, value];
- })
- );
- });
- }
-
- // type
- getDataGridExecTypeHeader() {
- return this.getDataGrid().should('exist').find('[data-cy=data-pipelines-job-executions-type-header]');
- }
-
- getDataGridExecTypeFilterOpenerBtn() {
- return this.getDataGridExecTypeHeader().should('exist').find('.datagrid-filter-toggle');
- }
-
- getDataGridExecTypeSortBtn() {
- return this.getDataGridExecTypeHeader().should('exist').find('.datagrid-column-title');
- }
-
- /**
- * ** Get type filter label
- *
- * @param {'manual'|'scheduled'} type
- * @return {Cypress.Chainable>}
- */
- getDataGridExecTypeFilterLabel(type) {
- return cy.get(`[data-cy=dp-job-executions-type-filter-label-${type}]`);
- }
-
- /**
- * ** Get type filter checkbox
- *
- * @param {'manual'|'scheduled'} type
- * @return {Cypress.Chainable>}
- */
- getDataGridExecTypeFilterCheckbox(type) {
- return cy.get(`[data-cy=dp-job-executions-type-filter-checkbox-${type}]`);
- }
-
- getDataGridExecTypeFilterCheckboxesStatuses() {
- return cy.get('[data-cy=dp-job-executions-type-filter-checkbox] input').then(($checkboxes) => {
- return cy.wrap(
- Array.from($checkboxes).map((checkbox) => {
- const key = checkbox.getAttribute('data-cy').split('-').pop();
- const value = checkbox.checked;
-
- return [key, value];
- })
- );
- });
- }
-
- // duration
- getDataGridExecDurationHeader() {
- return this.getDataGrid().should('exist').find('[data-cy=data-pipelines-job-executions-duration-header]');
- }
-
- getDataGridExecDurationFilterOpenerBtn() {
- return this.getDataGridExecDurationHeader().should('exist').find('.datagrid-filter-toggle');
- }
-
- getDataGridExecDurationSortBtn() {
- return this.getDataGridExecDurationHeader().should('exist').find('.datagrid-column-title');
- }
-
- // exec start
- getDataGridExecStartHeader() {
- return this.getDataGrid().should('exist').find('[data-cy=data-pipelines-job-executions-start-header]');
- }
-
- getDataGridExecStartFilterOpenerBtn() {
- return this.getDataGridExecStartHeader().should('exist').find('.datagrid-filter-toggle');
- }
-
- getDataGridExecStartSortBtn() {
- return this.getDataGridExecStartHeader().should('exist').find('.datagrid-column-title');
- }
-
- // exec end
- getDataGridExecEndHeader() {
- return this.getDataGrid().should('exist').find('[data-cy=data-pipelines-job-executions-end-header]');
- }
-
- getDataGridExecEndFilterOpenerBtn() {
- return this.getDataGridExecEndHeader().should('exist').find('.datagrid-filter-toggle');
- }
-
- getDataGridExecEndSortBtn() {
- return this.getDataGridExecEndHeader().should('exist').find('.datagrid-column-title');
- }
-
- // id
- getDataGridExecIDHeader() {
- return this.getDataGrid().should('exist').find('[data-cy=data-pipelines-job-executions-id-header]');
- }
-
- getDataGridExecIDFilterOpenerBtn() {
- return this.getDataGridExecIDHeader().should('exist').find('.datagrid-filter-toggle');
- }
-
- getDataGridExecIDSortBtn() {
- return this.getDataGridExecIDHeader().should('exist').find('.datagrid-column-title');
- }
-
- // version
- getDataGridExecVersionHeader() {
- return this.getDataGrid().should('exist').find('[data-cy=data-pipelines-job-executions-version-header]');
- }
-
- getDataGridExecVersionFilterOpenerBtn() {
- return this.getDataGridExecVersionHeader().should('exist').find('.datagrid-filter-toggle');
- }
-
- getDataGridExecVersionSortBtn() {
- return this.getDataGridExecVersionHeader().should('exist').find('.datagrid-column-title');
- }
-
- // Rows and Cells
-
- getDataGridRows() {
- return this.getDataGrid().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]);
- }
-
- getDataGridCells(rowIndex) {
- return this.getDataGridRow(rowIndex).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]);
+ });
+
+ this.waitForViewToRender();
+ }
+
+ /**
+ * ** Clear filter by some status.
+ *
+ * @param {'succeeded'|'platform_error'|'user_error'|'running'|'submitted'|'skipped'|'cancelled'} status
+ */
+ clearFilterByStatus(status) {
+ this.getDataGridExecStatusFilterCheckbox(status)
+ .should("exist")
+ .as("checkbox")
+ .invoke("is", ":checked")
+ .then((checked) => {
+ if (checked) {
+ this.getDataGridExecStatusFilterLabel(status)
+ .should("exist")
+ .click({ force: true });
}
+ });
+
+ this.waitForViewToRender();
+ }
+
+ sortByExecStatus() {
+ this.getDataGridExecStatusSortBtn().should("exist").click({ force: true });
+
+ this.waitForViewToRender();
+ }
+
+ // type
+ openTypeFilter() {
+ this.getDataGridExecTypeFilterOpenerBtn()
+ .should("exist")
+ .click({ force: true });
+
+ this.waitForViewToRenderShort();
+ }
+
+ /**
+ * ** Choose filter by some type.
+ *
+ * @param {'manual'|'scheduled'} type
+ */
+ filterByType(type) {
+ this.getDataGridExecTypeFilterCheckbox(type)
+ .should("exist")
+ .as("checkbox")
+ .invoke("is", ":checked")
+ .then((checked) => {
+ if (!checked) {
+ this.getDataGridExecTypeFilterLabel(type).click({
+ force: true,
+ });
+ }
+ });
+
+ this.waitForViewToRender();
+ }
+
+ /**
+ * ** Clear filter by some type.
+ *
+ * @param {'manual'|'scheduled'} type
+ */
+ clearFilterByType(type) {
+ this.getDataGridExecTypeFilterCheckbox(type)
+ .should("exist")
+ .as("checkbox")
+ .invoke("is", ":checked")
+ .then((checked) => {
+ if (checked) {
+ this.getDataGridExecTypeFilterLabel(type)
+ .should("exist")
+ .click({ force: true });
+ }
+ });
- return this.getDataGridRows()
- .should('have.length.gte', 0)
- .then(($rows) => {
- return $rows.reduce((accumulator, row) => {
- const _cells = Array.from(row.querySelectorAll('clr-dg-cell.datagrid-cell'));
-
- if (_cells[cellIndex - 1]) {
- accumulator.push(_cells[cellIndex - 1]);
- }
-
- return accumulator;
- }, []);
- });
- }
-
- getDataGridCellByIdentifier(rowIndex, identifier) {
- return this.getDataGridRow(rowIndex).should('exist').find(identifier);
- }
-
- getDataGridCellsByIdentifier(identifier) {
- return this.getDataGrid().should('exist').find(identifier);
- }
-
- // type
- getDataGridExecTypeCell(rowIndex) {
- return this.getDataGridCellByIdentifier(rowIndex, '[data-cy=data-pipelines-job-executions-type-cell]');
- }
-
- /**
- * ** Get containers in cells for given type.
- *
- * @param {'manual'|'scheduled'} type
- * @return {Cypress.Chainable>}
- */
- getDataGridExecTypeContainers(type) {
- return this.getDataGrid()
- .should('exist')
- .then(($gridContainer) => {
- /**
- * @type {JQuery}
- */
- const $containers = $gridContainer.find('[data-cy=data-pipelines-job-executions-type-container]');
-
- return cy.wrap($containers.length === 0 ? [] : $containers);
- })
- .then(($containers) => {
- return cy.wrap(
- Array.from($containers)
- .map((container) => container.getAttribute('title').toLowerCase())
- .filter((title) => new RegExp(`^${type}`).test(title))
- );
- });
- }
-
- // getDataGridExecStatusFilterCheckboxesStatuses() {
- // return cy.get('[data-cy=dp-job-executions-status-filter-checkbox] input')
- // .then(($checkboxes) => {
- // return cy.wrap(Array.from($checkboxes).map((checkbox) => {
- // const key = checkbox.getAttribute('data-cy').split('-').pop();
- // const value = checkbox.checked;
- //
- // return [key, value];
- // }));
- // });
- // }
-
- // duration
- getDataGridExecDurationCell(rowIndex) {
- return this.getDataGridCellByIdentifier(rowIndex, '[data-cy=data-pipelines-job-executions-duration-cell]');
- }
-
- // exec start
- getDataGridExecStartCell(rowIndex) {
- return this.getDataGridCellByIdentifier(rowIndex, '[data-cy=data-pipelines-job-executions-start-cell]');
- }
-
- getDataGridExecStartCells() {
- return this.getDataGridCellsByIdentifier('[data-cy=data-pipelines-job-executions-start-cell]');
- }
-
- generateExecStartFilterValue() {
- return this.getDataGridExecStartCells().then(($cells) => {
- const pmCells = Array.from($cells).map((cell) => /PM$/.test(`${cell.innerText?.trim()}`));
- if (pmCells.length >= 2) {
- return cy.wrap('PM');
- }
-
- const amCells = Array.from($cells).map((cell) => /AM$/.test(`${cell.innerText?.trim()}`));
- if (amCells.length >= 2) {
- return cy.wrap('AM');
- }
-
- throw new Error('Unhandled use case in test scenarios');
- });
- }
-
- // exec end
- getDataGridExecEndCell(rowIndex) {
- return this.getDataGridCellByIdentifier(rowIndex, '[data-cy=data-pipelines-job-executions-end-cell]');
- }
-
- getDataGridExecEndCells() {
- return this.getDataGridCellsByIdentifier('[data-cy=data-pipelines-job-executions-end-cell]');
- }
-
- generateExecEndFilterValue() {
- return this.getDataGridExecEndCells().then(($cells) => {
- const pmCells = Array.from($cells).map((cell) => /PM$/.test(`${cell.innerText?.trim()}`));
-
- if (pmCells.length > 0) {
- return cy.wrap('PM');
- }
-
- return cy.wrap('AM');
- });
- }
-
- // id
- getDataGridExecIDCell(rowIndex) {
- return this.getDataGridCellByIdentifier(rowIndex, '[data-cy=data-pipelines-job-executions-id-cell]');
- }
-
- getDataGridExecIDCells() {
- return this.getDataGridCellsByIdentifier('[data-cy=data-pipelines-job-executions-id-cell]');
- }
-
- // exec version
- getDataGridExecVersionCell(rowIndex) {
- return this.getDataGridCellByIdentifier(rowIndex, '[data-cy=data-pipelines-job-executions-job-version-cell]');
- }
-
- getDataGridExecVersionCells() {
- return this.getDataGridCellsByIdentifier('[data-cy=data-pipelines-job-executions-job-version-cell]');
- }
-
- // Pagination
-
- getDataGridPagination() {
- return this.getDataGrid().should('exist').find('[data-cy=data-pipelines-job-executions-datagrid-pagination]');
- }
-
- /* Actions */
-
- // General
-
- refreshExecData() {
- this.getExecRefreshBtn().should('exist').click({ force: true });
- }
-
- // DataGrid
-
- typeToTextFilterInput(value) {
- this.getDataGridInputFilter().should('exist').type(value);
-
- this.waitForViewToRender();
- }
-
- clearTextFilterInput() {
- this.getDataGridInputFilter().should('exist').clear({ force: true });
-
- this.waitForViewToRender();
- }
-
- closeFilter() {
- this.getDataGridPopupFilterCloseBtn().should('exist').click({ force: true });
-
- this.waitForViewToRenderShort();
- }
-
- // Header
-
- // status
- /**
- * ** Open status filter.
- */
- openStatusFilter() {
- this.getDataGridExecStatusFilterOpenerBtn().should('exist').click({ force: true });
-
- this.waitForViewToRenderShort();
- }
-
- /**
- * ** Choose filter by some status.
- *
- * @param {'succeeded'|'platform_error'|'user_error'|'running'|'submitted'|'skipped'|'cancelled'} status
- */
- filterByStatus(status) {
- this.getDataGridExecStatusFilterCheckbox(status)
- .should('exist')
- .as('checkbox')
- .invoke('is', ':checked')
- .then((checked) => {
- if (!checked) {
- this.getDataGridExecStatusFilterLabel(status).should('exist').click({ force: true });
- }
- });
-
- this.waitForViewToRender();
- }
-
- /**
- * ** Clear filter by some status.
- *
- * @param {'succeeded'|'platform_error'|'user_error'|'running'|'submitted'|'skipped'|'cancelled'} status
- */
- clearFilterByStatus(status) {
- this.getDataGridExecStatusFilterCheckbox(status)
- .should('exist')
- .as('checkbox')
- .invoke('is', ':checked')
- .then((checked) => {
- if (checked) {
- this.getDataGridExecStatusFilterLabel(status).should('exist').click({ force: true });
- }
- });
-
- this.waitForViewToRender();
- }
-
- sortByExecStatus() {
- this.getDataGridExecStatusSortBtn().should('exist').click({ force: true });
+ this.waitForViewToRender();
+ }
- this.waitForViewToRender();
- }
+ sortByExecType() {
+ this.getDataGridExecTypeSortBtn().should("exist").click({ force: true });
- // type
- openTypeFilter() {
- this.getDataGridExecTypeFilterOpenerBtn().should('exist').click({ force: true });
+ this.waitForViewToRender();
+ }
- this.waitForViewToRenderShort();
- }
+ // duration
+ openDurationFilter() {
+ this.getDataGridExecDurationFilterOpenerBtn()
+ .should("exist")
+ .click({ force: true });
- /**
- * ** Choose filter by some type.
- *
- * @param {'manual'|'scheduled'} type
- */
- filterByType(type) {
- this.getDataGridExecTypeFilterCheckbox(type)
- .should('exist')
- .as('checkbox')
- .invoke('is', ':checked')
- .then((checked) => {
- if (!checked) {
- this.getDataGridExecTypeFilterLabel(type).click({
- force: true
- });
- }
- });
-
- this.waitForViewToRender();
- }
+ this.waitForViewToRenderShort();
+ }
- /**
- * ** Clear filter by some type.
- *
- * @param {'manual'|'scheduled'} type
- */
- clearFilterByType(type) {
- this.getDataGridExecTypeFilterCheckbox(type)
- .should('exist')
- .as('checkbox')
- .invoke('is', ':checked')
- .then((checked) => {
- if (checked) {
- this.getDataGridExecTypeFilterLabel(type).should('exist').click({ force: true });
- }
- });
-
- this.waitForViewToRender();
- }
+ sortByExecDuration() {
+ this.getDataGridExecDurationSortBtn()
+ .should("exist")
+ .click({ force: true });
- sortByExecType() {
- this.getDataGridExecTypeSortBtn().should('exist').click({ force: true });
+ this.waitForViewToRender();
+ }
- this.waitForViewToRender();
- }
+ // exec start
+ openExecStartFilter() {
+ this.getDataGridExecStartFilterOpenerBtn()
+ .should("exist")
+ .click({ force: true });
- // duration
- openDurationFilter() {
- this.getDataGridExecDurationFilterOpenerBtn().should('exist').click({ force: true });
+ this.waitForViewToRenderShort();
+ }
- this.waitForViewToRenderShort();
- }
+ sortByExecStart() {
+ this.getDataGridExecStartSortBtn().should("exist").click({ force: true });
- sortByExecDuration() {
- this.getDataGridExecDurationSortBtn().should('exist').click({ force: true });
+ this.waitForViewToRender();
+ }
- this.waitForViewToRender();
- }
+ // exec end
+ openExecEndFilter() {
+ this.getDataGridExecEndFilterOpenerBtn()
+ .should("exist")
+ .click({ force: true });
- // exec start
- openExecStartFilter() {
- this.getDataGridExecStartFilterOpenerBtn().should('exist').click({ force: true });
+ this.waitForViewToRenderShort();
+ }
- this.waitForViewToRenderShort();
- }
+ sortByExecEnd() {
+ this.getDataGridExecEndSortBtn().should("exist").click({ force: true });
- sortByExecStart() {
- this.getDataGridExecStartSortBtn().should('exist').click({ force: true });
+ this.waitForViewToRender();
+ }
- this.waitForViewToRender();
- }
+ // id
+ openIDFilter() {
+ this.getDataGridExecIDFilterOpenerBtn()
+ .should("exist")
+ .click({ force: true });
- // exec end
- openExecEndFilter() {
- this.getDataGridExecEndFilterOpenerBtn().should('exist').click({ force: true });
+ this.waitForViewToRenderShort();
+ }
- this.waitForViewToRenderShort();
- }
+ sortByExecID() {
+ this.getDataGridExecIDSortBtn().should("exist").click({ force: true });
- sortByExecEnd() {
- this.getDataGridExecEndSortBtn().should('exist').click({ force: true });
+ this.waitForViewToRender();
+ }
- this.waitForViewToRender();
- }
+ // version
+ openVersionFilter() {
+ this.getDataGridExecVersionFilterOpenerBtn()
+ .should("exist")
+ .click({ force: true });
- // id
- openIDFilter() {
- this.getDataGridExecIDFilterOpenerBtn().should('exist').click({ force: true });
+ this.waitForViewToRenderShort();
+ }
- this.waitForViewToRenderShort();
- }
-
- sortByExecID() {
- this.getDataGridExecIDSortBtn().should('exist').click({ force: true });
+ sortByExecVersion() {
+ this.getDataGridExecVersionSortBtn().should("exist").click({ force: true });
- this.waitForViewToRender();
- }
-
- // version
- openVersionFilter() {
- this.getDataGridExecVersionFilterOpenerBtn().should('exist').click({ force: true });
-
- this.waitForViewToRenderShort();
- }
-
- sortByExecVersion() {
- this.getDataGridExecVersionSortBtn().should('exist').click({ force: true });
-
- this.waitForViewToRender();
- }
+ this.waitForViewToRender();
+ }
}
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 08e60c0f94..79730abe8a 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
@@ -7,55 +7,68 @@
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
- config.set({
- 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')],
- client: {
- jasmine: {
- // you can add configuration options for Jasmine here
- // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
- // 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
+ config.set({
+ 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"),
+ ],
+ client: {
+ jasmine: {
+ // you can add configuration options for Jasmine here
+ // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
+ // 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
+ },
+ jasmineHtmlReporter: {
+ suppressAll: true, // removes the duplicated traces
+ },
+ coverageReporter: {
+ 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" },
+ ],
+ check: {
+ global: {
+ lines: 80,
},
- jasmineHtmlReporter: {
- suppressAll: true // removes the duplicated traces
- },
- coverageReporter: {
- 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' }
- ],
- check: {
- global: {
- lines: 80
- }
- }
- },
- reporters: ['progress', 'junit', 'coverage'],
- junitReporter: {
- 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'],
- customLaunchers: {
- ChromeHeadless_No_Sandbox: {
- base: 'ChromeHeadless',
- flags: ['--no-sandbox']
- }
- },
- singleRun: false,
- restartOnFileChange: true
- });
+ },
+ },
+ reporters: ["progress", "junit", "coverage"],
+ junitReporter: {
+ 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"],
+ customLaunchers: {
+ ChromeHeadless_No_Sandbox: {
+ base: "ChromeHeadless",
+ flags: ["--no-sandbox"],
+ },
+ },
+ singleRun: false,
+ restartOnFileChange: true,
+ });
};
diff --git a/projects/frontend/data-pipelines/gui/projects/data-pipelines/src/lib/commons/filters-manager/filters-sort-manager.spec.ts b/projects/frontend/data-pipelines/gui/projects/data-pipelines/src/lib/commons/filters-manager/filters-sort-manager.spec.ts
index 6992df9056..92b1929911 100644
--- a/projects/frontend/data-pipelines/gui/projects/data-pipelines/src/lib/commons/filters-manager/filters-sort-manager.spec.ts
+++ b/projects/frontend/data-pipelines/gui/projects/data-pipelines/src/lib/commons/filters-manager/filters-sort-manager.spec.ts
@@ -3,1836 +3,2221 @@
* SPDX-License-Identifier: Apache-2.0
*/
-import { fakeAsync, tick } from '@angular/core/testing';
-
-import { CallFake, URLStateManager } from '@versatiledatakit/shared';
-
-import { FILTER_KEY, FiltersSortManager, KeyValueTuple, SORT_KEY } from './filters-sort-manager';
-
-const FILTER_CRITERIA_F1 = 'c1';
-const FILTER_CRITERIA_F2 = 'c2';
-const FILTER_CRITERIA_F3 = 'c3';
-const FILTER_CRITERIA_F4 = 'c4';
-const FILTER_CRITERIA_F5 = 'c5';
+import { fakeAsync, tick } from "@angular/core/testing";
+
+import { CallFake, URLStateManager } from "@versatiledatakit/shared";
+
+import {
+ FILTER_KEY,
+ FiltersSortManager,
+ KeyValueTuple,
+ SORT_KEY,
+} from "./filters-sort-manager";
+
+const FILTER_CRITERIA_F1 = "c1";
+const FILTER_CRITERIA_F2 = "c2";
+const FILTER_CRITERIA_F3 = "c3";
+const FILTER_CRITERIA_F4 = "c4";
+const FILTER_CRITERIA_F5 = "c5";
type FILTER_CRITERIA_UNION =
- | typeof FILTER_CRITERIA_F1
- | typeof FILTER_CRITERIA_F2
- | typeof FILTER_CRITERIA_F3
- | typeof FILTER_CRITERIA_F4
- | typeof FILTER_CRITERIA_F5;
-
-const SORT_CRITERIA_S1 = 'c1';
-const SORT_CRITERIA_S2 = 'c2';
-const SORT_CRITERIA_S3 = 'c3';
-const SORT_CRITERIA_S4 = 'c4';
-type SORT_CRITERIA_UNION = typeof SORT_CRITERIA_S1 | typeof SORT_CRITERIA_S2 | typeof SORT_CRITERIA_S3 | typeof SORT_CRITERIA_S4;
+ | typeof FILTER_CRITERIA_F1
+ | typeof FILTER_CRITERIA_F2
+ | typeof FILTER_CRITERIA_F3
+ | typeof FILTER_CRITERIA_F4
+ | typeof FILTER_CRITERIA_F5;
+
+const SORT_CRITERIA_S1 = "c1";
+const SORT_CRITERIA_S2 = "c2";
+const SORT_CRITERIA_S3 = "c3";
+const SORT_CRITERIA_S4 = "c4";
+type SORT_CRITERIA_UNION =
+ | typeof SORT_CRITERIA_S1
+ | typeof SORT_CRITERIA_S2
+ | typeof SORT_CRITERIA_S3
+ | typeof SORT_CRITERIA_S4;
const KNOWN_FILTER_CRITERIA: FILTER_CRITERIA_UNION[] = [
- FILTER_CRITERIA_F1,
- FILTER_CRITERIA_F2,
- FILTER_CRITERIA_F3,
- FILTER_CRITERIA_F4,
- FILTER_CRITERIA_F5
+ FILTER_CRITERIA_F1,
+ FILTER_CRITERIA_F2,
+ FILTER_CRITERIA_F3,
+ FILTER_CRITERIA_F4,
+ FILTER_CRITERIA_F5,
];
-const KNOWN_SORT_CRITERIA: SORT_CRITERIA_UNION[] = [SORT_CRITERIA_S1, SORT_CRITERIA_S2, SORT_CRITERIA_S3, SORT_CRITERIA_S4];
+const KNOWN_SORT_CRITERIA: SORT_CRITERIA_UNION[] = [
+ SORT_CRITERIA_S1,
+ SORT_CRITERIA_S2,
+ SORT_CRITERIA_S3,
+ SORT_CRITERIA_S4,
+];
class MutationObserver {
- observer(_changes: Array>): void {
- // No-op.
- }
+ observer(
+ _changes: Array<
+ KeyValueTuple
+ >,
+ ): void {
+ // No-op.
+ }
}
-describe('FiltersSortManager', () => {
- let urlStateManagerStub: jasmine.SpyObj;
+describe("FiltersSortManager", () => {
+ let urlStateManagerStub: jasmine.SpyObj;
+
+ beforeEach(() => {
+ urlStateManagerStub = jasmine.createSpyObj(
+ "urlStateManagerStub",
+ [
+ "changeBaseUrl",
+ "locationToURL",
+ "replaceToUrl",
+ "navigateToUrl",
+ "setQueryParam",
+ ],
+ );
+ });
+
+ it("should verify instance is created", () => {
+ // When
+ const instance = new FiltersSortManager<
+ FILTER_CRITERIA_UNION,
+ string,
+ SORT_CRITERIA_UNION,
+ string
+ >(urlStateManagerStub, KNOWN_FILTER_CRITERIA, KNOWN_SORT_CRITERIA);
+
+ // Then
+ expect(instance).toBeDefined();
+ });
+
+ describe("Properties::", () => {
+ let manager: FiltersSortManager<
+ FILTER_CRITERIA_UNION,
+ string,
+ SORT_CRITERIA_UNION,
+ string
+ >;
beforeEach(() => {
- urlStateManagerStub = jasmine.createSpyObj('urlStateManagerStub', [
- 'changeBaseUrl',
- 'locationToURL',
- 'replaceToUrl',
- 'navigateToUrl',
- 'setQueryParam'
+ manager = new FiltersSortManager(
+ urlStateManagerStub,
+ KNOWN_FILTER_CRITERIA,
+ KNOWN_SORT_CRITERIA,
+ );
+ });
+
+ describe("|filterCriteria|", () => {
+ it("should verify default value is empty object", () => {
+ // Then
+ expect(manager.filterCriteria).toEqual(
+ {} as Record,
+ );
+ });
+ });
+
+ describe("|sortCriteria|", () => {
+ it("should verify default value is empty object", () => {
+ // Then
+ expect(manager.sortCriteria).toEqual(
+ {} as Record,
+ );
+ });
+ });
+ });
+
+ describe("Methods::", () => {
+ let manager: FiltersSortManager<
+ FILTER_CRITERIA_UNION,
+ string,
+ SORT_CRITERIA_UNION,
+ string
+ >;
+
+ beforeEach(() => {
+ manager = new FiltersSortManager(
+ urlStateManagerStub,
+ KNOWN_FILTER_CRITERIA,
+ KNOWN_SORT_CRITERIA,
+ );
+ });
+
+ describe("|hasFilter|", () => {
+ it("should verify will return false when there is not such filter criteria", () => {
+ // Given
+ manager.filterCriteria[FILTER_CRITERIA_F1] = "f1v";
+ manager.filterCriteria[FILTER_CRITERIA_F2] = "f2v";
+
+ // Then 1
+ expect(manager.filterCriteria).toEqual({
+ [FILTER_CRITERIA_F1]: "f1v",
+ [FILTER_CRITERIA_F2]: "f2v",
+ } as Record);
+
+ // When/Then 2
+ expect(manager.hasFilter(FILTER_CRITERIA_F1)).toBeTrue();
+ expect(manager.hasFilter(FILTER_CRITERIA_F2)).toBeTrue();
+ expect(manager.hasFilter(FILTER_CRITERIA_F3)).toBeFalse();
+ expect(manager.hasFilter(FILTER_CRITERIA_F4)).toBeFalse();
+ expect(manager.hasFilter(FILTER_CRITERIA_F5)).toBeFalse();
+ });
+
+ it(`should verify will return false when there is such filter criteria but it's value is Nil`, () => {
+ // Given
+ manager.filterCriteria[FILTER_CRITERIA_F1] = "f1v";
+ manager.filterCriteria[FILTER_CRITERIA_F3] = null;
+ manager.filterCriteria[FILTER_CRITERIA_F5] = undefined;
+
+ // Then 1
+ expect(manager.filterCriteria).toEqual({
+ [FILTER_CRITERIA_F1]: "f1v",
+ [FILTER_CRITERIA_F3]: null,
+ [FILTER_CRITERIA_F5]: undefined,
+ } as Record);
+
+ // When/Then 2
+ expect(manager.hasFilter(FILTER_CRITERIA_F1)).toBeTrue();
+ expect(manager.hasFilter(FILTER_CRITERIA_F2)).toBeFalse();
+ expect(manager.hasFilter(FILTER_CRITERIA_F3)).toBeFalse();
+ expect(manager.hasFilter(FILTER_CRITERIA_F4)).toBeFalse();
+ expect(manager.hasFilter(FILTER_CRITERIA_F5)).toBeFalse();
+ });
+
+ it(`should verify will return true when there is such filter criteria and it's value is not Nil`, () => {
+ // Given
+ manager.filterCriteria[FILTER_CRITERIA_F2] = "f2v";
+ manager.filterCriteria[FILTER_CRITERIA_F3] = "f3v";
+
+ // Then 1
+ expect(manager.filterCriteria).toEqual({
+ [FILTER_CRITERIA_F2]: "f2v",
+ [FILTER_CRITERIA_F3]: "f3v",
+ } as Record);
+
+ // When/Then 2
+ expect(manager.hasFilter(FILTER_CRITERIA_F1)).toBeFalse();
+ expect(manager.hasFilter(FILTER_CRITERIA_F2)).toBeTrue();
+ expect(manager.hasFilter(FILTER_CRITERIA_F3)).toBeTrue();
+ expect(manager.hasFilter(FILTER_CRITERIA_F4)).toBeFalse();
+ expect(manager.hasFilter(FILTER_CRITERIA_F5)).toBeFalse();
+ });
+ });
+
+ describe("|hasAnyFilter|", () => {
+ it("should verify will return false when there is no filter criteria set", () => {
+ // Then 1
+ expect(manager.filterCriteria).toEqual(
+ {} as Record,
+ );
+
+ // Then 2
+ expect(manager.hasAnyFilter()).toBeFalse();
+ });
+
+ it(`should verify will return false when there are two filter criteria but their value is Nil`, () => {
+ // Given
+ manager.filterCriteria[FILTER_CRITERIA_F2] = null;
+ manager.filterCriteria[FILTER_CRITERIA_F4] = undefined;
+
+ // Then 1
+ expect(manager.filterCriteria).toEqual({
+ [FILTER_CRITERIA_F2]: null,
+ [FILTER_CRITERIA_F4]: undefined,
+ } as Record);
+
+ // When/Then 2
+ expect(manager.hasAnyFilter()).toBeFalse();
+ });
+
+ it(`should verify will return true when there is at least one filter criteria which value is not Nil`, () => {
+ // Given
+ manager.filterCriteria[FILTER_CRITERIA_F1] = null;
+ manager.filterCriteria[FILTER_CRITERIA_F2] = undefined;
+ manager.filterCriteria[FILTER_CRITERIA_F4] = "f4v";
+ manager.filterCriteria[FILTER_CRITERIA_F5] = "f5v";
+
+ // Then 1
+ expect(manager.filterCriteria).toEqual({
+ [FILTER_CRITERIA_F1]: null,
+ [FILTER_CRITERIA_F2]: undefined,
+ [FILTER_CRITERIA_F4]: "f4v",
+ [FILTER_CRITERIA_F5]: "f5v",
+ } as Record);
+
+ // When/Then 2
+ expect(manager.hasAnyFilter()).toBeTrue();
+ });
+ });
+
+ describe("|setFilter|", () => {
+ it(`should verify won't set filter if it exist and new value is same like stored one`, () => {
+ // Given
+ const filterValue1 = "f1v";
+ const mutationObserver = new MutationObserver();
+ const observerSpy = spyOn(
+ mutationObserver,
+ "observer",
+ ).and.callThrough();
+
+ // prerequisites manager should have
+ manager.filterCriteria[FILTER_CRITERIA_F1] = filterValue1;
+ manager.registerMutationObserver(mutationObserver.observer);
+
+ // Then 1
+ expect(manager.filterCriteria).toEqual({
+ [FILTER_CRITERIA_F1]: filterValue1,
+ } as Record);
+
+ // When
+ manager.setFilter(FILTER_CRITERIA_F1, filterValue1);
+
+ // Then 2
+ expect(manager.filterCriteria).toEqual({
+ [FILTER_CRITERIA_F1]: filterValue1,
+ } as Record);
+ expect(urlStateManagerStub.setQueryParam).not.toHaveBeenCalled();
+ expect(observerSpy).not.toHaveBeenCalled();
+
+ expect(urlStateManagerStub.locationToURL).not.toHaveBeenCalled();
+ expect(urlStateManagerStub.replaceToUrl).not.toHaveBeenCalled();
+ expect(urlStateManagerStub.navigateToUrl).not.toHaveBeenCalled();
+ });
+
+ it(`should verify will set filter if doesn't exist in manager, serialize to URLStateManager, update URL by default and notify mutation observers`, fakeAsync(() => {
+ // Given
+ const filterValue1 = "f1v";
+ const filterValue2 = "f2v";
+
+ // prerequisites manager should have
+ manager.filterCriteria[FILTER_CRITERIA_F2] = filterValue2;
+
+ // Then 1
+ expect(manager.filterCriteria).toEqual({
+ [FILTER_CRITERIA_F2]: filterValue2,
+ } as Record);
+
+ // When
+ manager.setFilter(FILTER_CRITERIA_F1, filterValue1);
+
+ // wait virtually 1s because navigation is debounced for 300ms by default
+ tick(1000);
+
+ // Then 2
+ expect(manager.filterCriteria).toEqual({
+ [FILTER_CRITERIA_F1]: filterValue1,
+ [FILTER_CRITERIA_F2]: filterValue2,
+ } as Record);
+ expect(urlStateManagerStub.setQueryParam).toHaveBeenCalledWith(
+ FILTER_KEY,
+ JSON.stringify({
+ [FILTER_CRITERIA_F2]: filterValue2,
+ [FILTER_CRITERIA_F1]: filterValue1,
+ }),
+ );
+
+ expect(urlStateManagerStub.locationToURL).toHaveBeenCalledTimes(1);
+ expect(urlStateManagerStub.replaceToUrl).not.toHaveBeenCalled();
+ expect(urlStateManagerStub.navigateToUrl).not.toHaveBeenCalled();
+ }));
+
+ it(`should verify will delete filter if exist in manager because provided value is Nil, serialize to URLStateManager, update URL by default and notify mutation observers`, fakeAsync(() => {
+ // Given
+ const filterValue3 = "f3v";
+ const filterValue4 = "f4v";
+ const mutationObserver = new MutationObserver();
+ const observerSpy = spyOn(
+ mutationObserver,
+ "observer",
+ ).and.callThrough();
+
+ // prerequisites manager should have
+ manager.filterCriteria[FILTER_CRITERIA_F3] = filterValue3;
+ manager.filterCriteria[FILTER_CRITERIA_F4] = filterValue4;
+ manager.changeUpdateStrategy("replaceToURL");
+ manager.registerMutationObserver(mutationObserver.observer);
+
+ // Then 1
+ expect(manager.filterCriteria).toEqual({
+ [FILTER_CRITERIA_F3]: filterValue3,
+ [FILTER_CRITERIA_F4]: filterValue4,
+ } as Record);
+
+ // When
+ manager.setFilter(FILTER_CRITERIA_F3, null);
+
+ // wait virtually 1s because navigation is debounced for 300ms by default
+ tick(1000);
+
+ // Then 2
+ expect(manager.filterCriteria).toEqual({
+ [FILTER_CRITERIA_F4]: filterValue4,
+ } as Record);
+ expect(urlStateManagerStub.setQueryParam).toHaveBeenCalledWith(
+ FILTER_KEY,
+ JSON.stringify({ [FILTER_CRITERIA_F4]: filterValue4 }),
+ );
+ expect(observerSpy).toHaveBeenCalledWith([
+ [FILTER_CRITERIA_F3, null, "filter"],
+ ]);
+
+ expect(urlStateManagerStub.locationToURL).not.toHaveBeenCalled();
+ expect(urlStateManagerStub.replaceToUrl).toHaveBeenCalledTimes(1);
+ expect(urlStateManagerStub.navigateToUrl).not.toHaveBeenCalled();
+ }));
+
+ it(`should verify will delete filters multiple times and update URL by default only once`, fakeAsync(() => {
+ // Given
+ const filterValue3 = "f3v";
+ const filterValue4 = "f4v";
+ const mutationObserver = new MutationObserver();
+ const observerSpy = spyOn(
+ mutationObserver,
+ "observer",
+ ).and.callThrough();
+
+ urlStateManagerStub.navigateToUrl.and.resolveTo(true);
+
+ // prerequisites manager should have
+ manager.filterCriteria[FILTER_CRITERIA_F3] = filterValue3;
+ manager.filterCriteria[FILTER_CRITERIA_F4] = filterValue4;
+ manager.changeUpdateStrategy("navigateToUrl");
+ manager.registerMutationObserver(mutationObserver.observer);
+
+ // Then 1
+ expect(manager.filterCriteria).toEqual({
+ [FILTER_CRITERIA_F3]: filterValue3,
+ [FILTER_CRITERIA_F4]: filterValue4,
+ } as Record);
+
+ // When
+ manager.setFilter(FILTER_CRITERIA_F3, null);
+ manager.setFilter(FILTER_CRITERIA_F4, null);
+
+ // wait virtually 1s because navigation is debounced for 300ms by default
+ tick(1000);
+
+ // Then 2
+ expect(manager.filterCriteria).toEqual(
+ {} as Record,
+ );
+ expect(urlStateManagerStub.setQueryParam.calls.argsFor(0)).toEqual([
+ FILTER_KEY,
+ JSON.stringify({ [FILTER_CRITERIA_F4]: filterValue4 }),
+ ]);
+ expect(urlStateManagerStub.setQueryParam.calls.argsFor(1)).toEqual([
+ FILTER_KEY,
+ null,
+ ]);
+ expect(observerSpy.calls.argsFor(0)).toEqual([
+ [[FILTER_CRITERIA_F3, null, "filter"]],
]);
+ expect(observerSpy.calls.argsFor(1)).toEqual([
+ [[FILTER_CRITERIA_F4, null, "filter"]],
+ ]);
+
+ expect(urlStateManagerStub.locationToURL).not.toHaveBeenCalled();
+ expect(urlStateManagerStub.replaceToUrl).not.toHaveBeenCalled();
+ expect(urlStateManagerStub.navigateToUrl).toHaveBeenCalledTimes(1);
+ }));
+
+ it(`should verify won't update URL if updateBrowserUrl parameter is false`, fakeAsync(() => {
+ // Given
+ const filterValue4 = "f4v";
+ const filterValue5 = "f5v";
+ const mutationObserver1 = new MutationObserver();
+ const mutationObserver2 = new MutationObserver();
+ const observerError = new Error("observer throws error");
+ const observerSpy1 = spyOn(
+ mutationObserver1,
+ "observer",
+ ).and.throwError(observerError);
+ const observerSpy2 = spyOn(
+ mutationObserver2,
+ "observer",
+ ).and.callThrough();
+ const consoleErrorSpy = spyOn(console, "error").and.callFake(CallFake);
+
+ // prerequisites manager should have
+ manager.filterCriteria[FILTER_CRITERIA_F4] = filterValue4;
+ manager.registerMutationObserver(mutationObserver1.observer);
+ manager.registerMutationObserver(mutationObserver2.observer);
+
+ // Then 1
+ expect(manager.filterCriteria).toEqual({
+ [FILTER_CRITERIA_F4]: filterValue4,
+ } as Record);
+
+ // When
+ manager.setFilter(FILTER_CRITERIA_F5, filterValue5, false);
+
+ // wait virtually 1s because navigation is debounced for 300ms by default
+ tick(1000);
+
+ // Then 2
+ expect(manager.filterCriteria).toEqual({
+ [FILTER_CRITERIA_F4]: filterValue4,
+ [FILTER_CRITERIA_F5]: filterValue5,
+ } as Record);
+ expect(urlStateManagerStub.setQueryParam).toHaveBeenCalledWith(
+ FILTER_KEY,
+ JSON.stringify({
+ [FILTER_CRITERIA_F4]: filterValue4,
+ [FILTER_CRITERIA_F5]: filterValue5,
+ }),
+ );
+ expect(observerSpy1).toHaveBeenCalledWith([
+ [FILTER_CRITERIA_F5, filterValue5, "filter"],
+ ]);
+ expect(observerSpy2).toHaveBeenCalledWith([
+ [FILTER_CRITERIA_F5, filterValue5, "filter"],
+ ]);
+
+ expect(consoleErrorSpy).toHaveBeenCalledWith(
+ "FiltersManager: Failed to notify mutation observers",
+ observerError,
+ );
+
+ expect(urlStateManagerStub.locationToURL).not.toHaveBeenCalled();
+ expect(urlStateManagerStub.replaceToUrl).not.toHaveBeenCalled();
+ expect(urlStateManagerStub.navigateToUrl).not.toHaveBeenCalled();
+ }));
+
+ it(`should verify will log error if update URL with navigateToUrl strategy fails`, fakeAsync(() => {
+ // Given
+ const filterValue3 = "f3v";
+ const navigateToUrlError = new Error("urlUpdateManager throws error");
+ const consoleErrorSpy = spyOn(console, "error").and.callFake(CallFake);
+
+ urlStateManagerStub.navigateToUrl.and.rejectWith(navigateToUrlError);
+
+ // prerequisites manager should have
+ manager.changeUpdateStrategy("navigateToUrl");
+
+ // Then 1
+ expect(manager.filterCriteria).toEqual(
+ {} as Record,
+ );
+
+ // When
+ manager.setFilter(FILTER_CRITERIA_F3, filterValue3, true);
+
+ // wait virtually 1s because navigation is debounced for 300ms by default
+ tick(1000);
+
+ // Then 2
+ expect(manager.filterCriteria).toEqual({
+ [FILTER_CRITERIA_F3]: filterValue3,
+ } as Record);
+ expect(urlStateManagerStub.setQueryParam).toHaveBeenCalledWith(
+ FILTER_KEY,
+ JSON.stringify({ [FILTER_CRITERIA_F3]: filterValue3 }),
+ );
+
+ expect(urlStateManagerStub.locationToURL).not.toHaveBeenCalled();
+ expect(urlStateManagerStub.replaceToUrl).not.toHaveBeenCalled();
+ expect(urlStateManagerStub.navigateToUrl).toHaveBeenCalledTimes(1);
+
+ expect(consoleErrorSpy).toHaveBeenCalledWith(
+ "FiltersManager: Failed to update Browser Url",
+ navigateToUrlError,
+ );
+ }));
});
- it('should verify instance is created', () => {
+ describe("|deleteFilter|", () => {
+ it(`should verify won't delete filter if it doesn't exist`, () => {
+ // Given
+ const filterValue4 = "f4v";
+ const mutationObserver = new MutationObserver();
+ const observerSpy = spyOn(
+ mutationObserver,
+ "observer",
+ ).and.callThrough();
+
+ // prerequisites manager should have
+ manager.filterCriteria[FILTER_CRITERIA_F4] = filterValue4;
+ manager.registerMutationObserver(mutationObserver.observer);
+
+ // Then 1
+ expect(manager.filterCriteria).toEqual({
+ [FILTER_CRITERIA_F4]: filterValue4,
+ } as Record);
+
// When
- const instance = new FiltersSortManager(
- urlStateManagerStub,
- KNOWN_FILTER_CRITERIA,
- KNOWN_SORT_CRITERIA
+ const returnedValue = manager.deleteFilter(FILTER_CRITERIA_F2);
+
+ // Then 2
+ expect(returnedValue).toBeFalse();
+ expect(manager.filterCriteria).toEqual({
+ [FILTER_CRITERIA_F4]: filterValue4,
+ } as Record);
+
+ expect(urlStateManagerStub.setQueryParam).not.toHaveBeenCalled();
+ expect(observerSpy).not.toHaveBeenCalled();
+
+ expect(urlStateManagerStub.locationToURL).not.toHaveBeenCalled();
+ expect(urlStateManagerStub.replaceToUrl).not.toHaveBeenCalled();
+ expect(urlStateManagerStub.navigateToUrl).not.toHaveBeenCalled();
+ });
+
+ it(`should verify will delete filter if it exist in manager, serialize to URLStateManager, update URL by default and notify mutation observers`, fakeAsync(() => {
+ // Given
+ const filterValue1 = "f1v";
+ const filterValue2 = "f2v";
+ const mutationObserver = new MutationObserver();
+ const observerSpy = spyOn(
+ mutationObserver,
+ "observer",
+ ).and.callThrough();
+
+ // prerequisites manager should have
+ manager.filterCriteria[FILTER_CRITERIA_F1] = filterValue1;
+ manager.filterCriteria[FILTER_CRITERIA_F2] = filterValue2;
+ manager.registerMutationObserver(mutationObserver.observer);
+
+ // Then 1
+ expect(manager.filterCriteria).toEqual({
+ [FILTER_CRITERIA_F1]: filterValue1,
+ [FILTER_CRITERIA_F2]: filterValue2,
+ } as Record);
+
+ // When
+ const returnedValue = manager.deleteFilter(FILTER_CRITERIA_F1);
+
+ // wait virtually 1s because navigation is debounced for 300ms by default
+ tick(1000);
+
+ // Then 2
+ expect(returnedValue).toBeTrue();
+
+ expect(manager.filterCriteria).toEqual({
+ [FILTER_CRITERIA_F2]: filterValue2,
+ } as Record);
+ expect(urlStateManagerStub.setQueryParam).toHaveBeenCalledWith(
+ FILTER_KEY,
+ JSON.stringify({ [FILTER_CRITERIA_F2]: filterValue2 }),
);
+ expect(observerSpy).toHaveBeenCalledWith([
+ [FILTER_CRITERIA_F1, null, "filter"],
+ ]);
- // Then
- expect(instance).toBeDefined();
+ expect(urlStateManagerStub.locationToURL).toHaveBeenCalledTimes(1);
+ expect(urlStateManagerStub.replaceToUrl).not.toHaveBeenCalled();
+ expect(urlStateManagerStub.navigateToUrl).not.toHaveBeenCalled();
+ }));
+
+ it(`should verify will delete filters multiple times and update URL by default only once`, fakeAsync(() => {
+ // Given
+ const filterValue1 = "f1v";
+ const filterValue2 = "f2v";
+ const mutationObserver = new MutationObserver();
+ const observerSpy = spyOn(
+ mutationObserver,
+ "observer",
+ ).and.callThrough();
+
+ urlStateManagerStub.navigateToUrl.and.resolveTo(true);
+
+ // prerequisites manager should have
+ manager.filterCriteria[FILTER_CRITERIA_F1] = filterValue1;
+ manager.filterCriteria[FILTER_CRITERIA_F2] = filterValue2;
+ manager.changeUpdateStrategy("navigateToUrl");
+ manager.registerMutationObserver(mutationObserver.observer);
+
+ // Then 1
+ expect(manager.filterCriteria).toEqual({
+ [FILTER_CRITERIA_F1]: filterValue1,
+ [FILTER_CRITERIA_F2]: filterValue2,
+ } as Record);
+
+ // When
+ const returnedValue1 = manager.deleteFilter(FILTER_CRITERIA_F1);
+ const returnedValue2 = manager.deleteFilter(FILTER_CRITERIA_F2);
+
+ // wait virtually 1s because navigation is debounced for 300ms by default
+ tick(1000);
+
+ // Then 2
+ expect(returnedValue1).toBeTrue();
+ expect(returnedValue2).toBeTrue();
+
+ expect(manager.filterCriteria).toEqual(
+ {} as Record,
+ );
+ expect(urlStateManagerStub.setQueryParam.calls.argsFor(0)).toEqual([
+ FILTER_KEY,
+ JSON.stringify({ [FILTER_CRITERIA_F2]: filterValue2 }),
+ ]);
+ expect(urlStateManagerStub.setQueryParam.calls.argsFor(1)).toEqual([
+ FILTER_KEY,
+ null,
+ ]);
+ expect(observerSpy.calls.argsFor(0)).toEqual([
+ [[FILTER_CRITERIA_F1, null, "filter"]],
+ ]);
+ expect(observerSpy.calls.argsFor(1)).toEqual([
+ [[FILTER_CRITERIA_F2, null, "filter"]],
+ ]);
+
+ expect(urlStateManagerStub.locationToURL).not.toHaveBeenCalled();
+ expect(urlStateManagerStub.replaceToUrl).not.toHaveBeenCalled();
+ expect(urlStateManagerStub.navigateToUrl).toHaveBeenCalledTimes(1);
+ }));
+
+ it(`should verify won't update URL if updateBrowserUrl parameter is false`, fakeAsync(() => {
+ // Given
+ const filterValue1 = "f1v";
+ const filterValue2 = "f2v";
+ const mutationObserver1 = new MutationObserver();
+ const mutationObserver2 = new MutationObserver();
+ const observerError = new Error("observer throws error");
+ const observerSpy1 = spyOn(
+ mutationObserver1,
+ "observer",
+ ).and.throwError(observerError);
+ const observerSpy2 = spyOn(
+ mutationObserver2,
+ "observer",
+ ).and.callThrough();
+ const consoleErrorSpy = spyOn(console, "error").and.callFake(CallFake);
+
+ // prerequisites manager should have
+ manager.filterCriteria[FILTER_CRITERIA_F1] = filterValue1;
+ manager.filterCriteria[FILTER_CRITERIA_F2] = filterValue2;
+ manager.registerMutationObserver(mutationObserver1.observer);
+ manager.registerMutationObserver(mutationObserver2.observer);
+
+ // Then 1
+ expect(manager.filterCriteria).toEqual({
+ [FILTER_CRITERIA_F1]: filterValue1,
+ [FILTER_CRITERIA_F2]: filterValue2,
+ } as Record);
+
+ // When
+ const returnedValue = manager.deleteFilter(FILTER_CRITERIA_F1, false);
+
+ // wait virtually 1s because navigation is debounced for 300ms by default
+ tick(1000);
+
+ // Then 2
+ expect(returnedValue).toBeTrue();
+
+ expect(manager.filterCriteria).toEqual({
+ [FILTER_CRITERIA_F2]: filterValue2,
+ } as Record);
+ expect(urlStateManagerStub.setQueryParam).toHaveBeenCalledWith(
+ FILTER_KEY,
+ JSON.stringify({ [FILTER_CRITERIA_F2]: filterValue2 }),
+ );
+ expect(observerSpy1).toHaveBeenCalledWith([
+ [FILTER_CRITERIA_F1, null, "filter"],
+ ]);
+ expect(observerSpy2).toHaveBeenCalledWith([
+ [FILTER_CRITERIA_F1, null, "filter"],
+ ]);
+
+ expect(consoleErrorSpy).toHaveBeenCalledWith(
+ "FiltersManager: Failed to notify mutation observers",
+ observerError,
+ );
+
+ expect(urlStateManagerStub.locationToURL).not.toHaveBeenCalled();
+ expect(urlStateManagerStub.replaceToUrl).not.toHaveBeenCalled();
+ expect(urlStateManagerStub.navigateToUrl).not.toHaveBeenCalled();
+ }));
});
- describe('Properties::', () => {
- let manager: FiltersSortManager;
+ describe("|clearFilters|", () => {
+ let observerError: Error;
+ let observerSpy1: jasmine.Spy;
+ let observerSpy2: jasmine.Spy;
+ let consoleErrorSpy: jasmine.Spy;
+
+ beforeEach(() => {
+ const filterValue1 = "f1v";
+ const filterValue2 = "f2v";
+
+ const mutationObserver1 = new MutationObserver();
+ const mutationObserver2 = new MutationObserver();
+ observerError = new Error("observer throws error");
+ observerSpy1 = spyOn(mutationObserver1, "observer").and.throwError(
+ observerError,
+ );
+ observerSpy2 = spyOn(mutationObserver2, "observer").and.callThrough();
+ consoleErrorSpy = spyOn(console, "error").and.callFake(CallFake);
+
+ // prerequisites manager should have
+ manager.filterCriteria[FILTER_CRITERIA_F1] = filterValue1;
+ manager.filterCriteria[FILTER_CRITERIA_F2] = filterValue2;
+ manager.filterCriteria[FILTER_CRITERIA_F3] = null;
+ manager.filterCriteria[FILTER_CRITERIA_F4] = undefined;
+ manager.registerMutationObserver(mutationObserver1.observer);
+ manager.registerMutationObserver(mutationObserver2.observer);
+
+ // Then 1
+ expect(manager.filterCriteria).toEqual({
+ [FILTER_CRITERIA_F1]: filterValue1,
+ [FILTER_CRITERIA_F2]: filterValue2,
+ [FILTER_CRITERIA_F3]: null,
+ [FILTER_CRITERIA_F4]: undefined,
+ } as Record);
+ });
+
+ it(`should verify will clear all existing filters, serialize to URLStateManager, update URL by default and notify mutation observers`, fakeAsync(() => {
+ // When
+ manager.clearFilters();
+ manager.clearFilters();
- beforeEach(() => {
- manager = new FiltersSortManager(urlStateManagerStub, KNOWN_FILTER_CRITERIA, KNOWN_SORT_CRITERIA);
- });
+ // wait virtually 1s because navigation is debounced for 300ms by default
+ tick(1000);
- describe('|filterCriteria|', () => {
- it('should verify default value is empty object', () => {
- // Then
- expect(manager.filterCriteria).toEqual({} as Record);
- });
- });
+ // Then
+ expect(manager.filterCriteria).toEqual(
+ {} as Record,
+ );
- describe('|sortCriteria|', () => {
- it('should verify default value is empty object', () => {
- // Then
- expect(manager.sortCriteria).toEqual({} as Record);
- });
- });
+ expect(urlStateManagerStub.setQueryParam).toHaveBeenCalledWith(
+ FILTER_KEY,
+ null,
+ );
+
+ expect(observerSpy1.calls.count()).toEqual(1);
+ expect(observerSpy1.calls.argsFor(0)).toEqual([
+ [
+ [FILTER_CRITERIA_F1, null, "filter"],
+ [FILTER_CRITERIA_F2, null, "filter"],
+ [FILTER_CRITERIA_F3, null, "filter"],
+ [FILTER_CRITERIA_F4, null, "filter"],
+ ],
+ ]);
+
+ expect(observerSpy2.calls.count()).toEqual(1);
+ expect(observerSpy2.calls.argsFor(0)).toEqual([
+ [
+ [FILTER_CRITERIA_F1, null, "filter"],
+ [FILTER_CRITERIA_F2, null, "filter"],
+ [FILTER_CRITERIA_F3, null, "filter"],
+ [FILTER_CRITERIA_F4, null, "filter"],
+ ],
+ ]);
+
+ expect(consoleErrorSpy).toHaveBeenCalledWith(
+ "FiltersManager: Failed to notify mutation observers",
+ observerError,
+ );
+
+ expect(urlStateManagerStub.locationToURL).toHaveBeenCalledTimes(1);
+ expect(urlStateManagerStub.replaceToUrl).not.toHaveBeenCalled();
+ expect(urlStateManagerStub.navigateToUrl).not.toHaveBeenCalled();
+ }));
+
+ it(`should verify will clear all existing filters, serialize to URLStateManager, and won't update URL and would notify mutation observers`, fakeAsync(() => {
+ // When
+ manager.clearFilters(false);
+ manager.clearFilters(false);
+
+ // wait virtually 1s because navigation is debounced for 300ms by default
+ tick(1000);
+
+ // Then
+ expect(manager.filterCriteria).toEqual(
+ {} as Record,
+ );
+
+ expect(urlStateManagerStub.setQueryParam).toHaveBeenCalledWith(
+ FILTER_KEY,
+ null,
+ );
+
+ expect(observerSpy1.calls.count()).toEqual(1);
+ expect(observerSpy1).toHaveBeenCalledWith([
+ [FILTER_CRITERIA_F1, null, "filter"],
+ [FILTER_CRITERIA_F2, null, "filter"],
+ [FILTER_CRITERIA_F3, null, "filter"],
+ [FILTER_CRITERIA_F4, null, "filter"],
+ ]);
+
+ expect(observerSpy2.calls.count()).toEqual(1);
+ expect(observerSpy2).toHaveBeenCalledWith([
+ [FILTER_CRITERIA_F1, null, "filter"],
+ [FILTER_CRITERIA_F2, null, "filter"],
+ [FILTER_CRITERIA_F3, null, "filter"],
+ [FILTER_CRITERIA_F4, null, "filter"],
+ ]);
+
+ expect(consoleErrorSpy).toHaveBeenCalledWith(
+ "FiltersManager: Failed to notify mutation observers",
+ observerError,
+ );
+
+ expect(urlStateManagerStub.locationToURL).not.toHaveBeenCalled();
+ expect(urlStateManagerStub.replaceToUrl).not.toHaveBeenCalled();
+ expect(urlStateManagerStub.navigateToUrl).not.toHaveBeenCalled();
+ }));
+
+ it(`should verify will clear all existing filters, serialize to URLStateManager, update URL by default and won't notify mutation observers`, fakeAsync(() => {
+ // Given
+ manager.changeUpdateStrategy("replaceToURL");
+
+ // When
+ manager.clearFilters(true, false);
+ manager.clearFilters(true);
+
+ // wait virtually 1s because navigation is debounced for 300ms by default
+ tick(1000);
+
+ // Then
+ expect(manager.filterCriteria).toEqual(
+ {} as Record