This is an automated email from the ASF dual-hosted git repository.
dominikriemer pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/streampipes.git
The following commit(s) were added to refs/heads/dev by this push:
new 294e57826e test: Add cypress tests for progress bar and value card
(#4579)
294e57826e is described below
commit 294e57826e5ed82883faceba2b496e6a178974b6
Author: Dominik Riemer <[email protected]>
AuthorDate: Tue Jun 16 12:57:31 2026 +0200
test: Add cypress tests for progress bar and value card (#4579)
---
ui/cypress/support/utils/chart/ChartBtns.ts | 118 ++++++++++++++++++++-
.../support/utils/chart/ChartWidgetTableUtils.ts | 8 ++
.../tests/chart/chart-types/progress-bar.spec.ts | 58 ++++++++++
ui/cypress/tests/chart/chart-types/table.spec.ts | 18 ++++
.../{table.spec.ts => value-card.spec.ts} | 28 +++--
.../progress-bar-widget-config.component.html | 48 +++++----
.../progress-bar-widget.component.html | 38 +++++--
.../charts/table/table-widget.component.html | 11 +-
.../config/value-card-widget-config.component.html | 3 +
.../value-card/value-card-widget.component.html | 30 ++++--
.../result-label-configuration.component.html | 4 +
11 files changed, 322 insertions(+), 42 deletions(-)
diff --git a/ui/cypress/support/utils/chart/ChartBtns.ts
b/ui/cypress/support/utils/chart/ChartBtns.ts
index 70bf1499dd..5b24ae3e95 100644
--- a/ui/cypress/support/utils/chart/ChartBtns.ts
+++ b/ui/cypress/support/utils/chart/ChartBtns.ts
@@ -120,7 +120,7 @@ export class ChartBtns {
}
public static editDataViewButton(dataViewName: string) {
- return cy.dataCy('edit-data-view-' + dataViewName.replaceAll(' ', ''));
+ return cy.dataCy('edit-data-view-' + dataViewName.replace(/ /g, ''));
}
public static chartSyncProblemIcon() {
@@ -213,6 +213,112 @@ export class ChartBtns {
.find('input[type="checkbox"]');
}
+ public static valueCardWidget() {
+ return cy.dataCy('value-card-widget');
+ }
+
+ public static valueCardTitleInput() {
+ return cy.dataCy('data-explorer-value-card-title-input');
+ }
+
+ public static valueCardDescriptionInput() {
+ return cy.dataCy('data-explorer-value-card-description-input');
+ }
+
+ public static valueCardShowTimestampCheckbox() {
+ return cy
+ .dataCy('data-explorer-value-card-show-timestamp')
+ .find('input[type="checkbox"]');
+ }
+
+ public static valueCardTitle() {
+ return cy.dataCy('value-card-title');
+ }
+
+ public static valueCardDescription() {
+ return cy.dataCy('value-card-description');
+ }
+
+ public static valueCardTimestamp() {
+ return cy.dataCy('value-card-timestamp');
+ }
+
+ public static valueCardItems() {
+ return cy.dataCy('value-card-item', {}, true);
+ }
+
+ public static valueCardItemLabels() {
+ return cy.dataCy('value-card-item-label', {}, true);
+ }
+
+ public static valueCardItemValues() {
+ return cy.dataCy('value-card-item-value', {}, true);
+ }
+
+ public static progressBarWidget() {
+ return cy.dataCy('progress-bar-widget');
+ }
+
+ public static progressBarTitleInput() {
+ return cy.dataCy('data-explorer-progress-title-input');
+ }
+
+ public static progressBarDescriptionInput() {
+ return cy.dataCy('data-explorer-progress-description-input');
+ }
+
+ public static progressBarTargetSource() {
+ return cy.dataCy('data-explorer-progress-target-source');
+ }
+
+ public static progressBarTargetValueInput() {
+ return cy.dataCy('data-explorer-progress-target-value');
+ }
+
+ public static progressBarDisplayMode() {
+ return cy.dataCy('data-explorer-progress-display-mode');
+ }
+
+ public static progressBarInvertCheckbox() {
+ return cy
+ .dataCy('data-explorer-progress-invert')
+ .find('input[type="checkbox"]');
+ }
+
+ public static progressBarShowLabelCheckbox() {
+ return cy
+ .dataCy('data-explorer-progress-show-label')
+ .find('input[type="checkbox"]');
+ }
+
+ public static progressBarTitle() {
+ return cy.dataCy('progress-bar-title');
+ }
+
+ public static progressBarDescription() {
+ return cy.dataCy('progress-bar-description');
+ }
+
+ public static progressBarStatus() {
+ return cy.dataCy('progress-bar-status');
+ }
+
+ public static progressBarPercent() {
+ return cy.dataCy('progress-bar-percent');
+ }
+
+ public static progressBarFill() {
+ return cy.dataCy('progress-bar-fill');
+ }
+
+ public static progressBarPrimaryLabel() {
+ return cy.dataCy('progress-bar-primary-label');
+ }
+
+ public static progressBarSecondaryLabel() {
+ return cy.dataCy('progress-bar-secondary-label');
+ }
+
public static addNewWidgetBtn() {
return cy.dataCy('add-new-widget', { timeout: 10000 });
}
@@ -305,6 +411,16 @@ export class ChartBtns {
return cy.dataCy('data-explorer-table-paginator');
}
+ public static resultLabelInput(fieldName: string) {
+ return cy.get(
+ `[data-cy="data-explorer-result-label-input-${fieldName}"]`,
+ );
+ }
+
+ public static tableHeader(fieldName: string) {
+ return cy.get(`[data-cy="data-explorer-table-header-${fieldName}"]`);
+ }
+
public static matOptionByText(text: string | RegExp) {
return cy.get('mat-option').contains(text);
}
diff --git a/ui/cypress/support/utils/chart/ChartWidgetTableUtils.ts
b/ui/cypress/support/utils/chart/ChartWidgetTableUtils.ts
index 9c58916837..68b4893b93 100644
--- a/ui/cypress/support/utils/chart/ChartWidgetTableUtils.ts
+++ b/ui/cypress/support/utils/chart/ChartWidgetTableUtils.ts
@@ -16,6 +16,8 @@
*
*/
+import { ChartBtns } from './ChartBtns';
+
export class ChartWidgetTableUtils {
public static chartTableRows() {
return cy
@@ -45,4 +47,10 @@ export class ChartWidgetTableUtils {
public static checkTotalAmountOfRows(amount: number) {
this.paginatorRangeLabel().should('contain.text', amount.toString());
}
+
+ public static checkHeaderLabel(fieldName: string, expectedLabel: string) {
+ ChartBtns.tableHeader(fieldName).should($header => {
+ expect($header.text().trim()).to.equal(expectedLabel);
+ });
+ }
}
diff --git a/ui/cypress/tests/chart/chart-types/progress-bar.spec.ts
b/ui/cypress/tests/chart/chart-types/progress-bar.spec.ts
new file mode 100644
index 0000000000..924f744214
--- /dev/null
+++ b/ui/cypress/tests/chart/chart-types/progress-bar.spec.ts
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { ChartUtils } from '../../../support/utils/chart/ChartUtils';
+import { PrepareTestDataUtils } from
'../../../support/utils/PrepareTestDataUtils';
+import { ChartBtns } from '../../../support/utils/chart/ChartBtns';
+
+describe('Test Progress Bar View in Charts', () => {
+ beforeEach('Setup Test', () => {
+ ChartUtils.initDataLakeTests();
+ });
+
+ it('Perform Test', () => {
+ ChartUtils.addDataViewAndWidget(
+ PrepareTestDataUtils.dataName,
+ 'progress-bar',
+ );
+
+ ChartUtils.openVisualizationConfig();
+ ChartBtns.progressBarTitleInput().type('Job Progress');
+ ChartBtns.progressBarDescriptionInput().type(
+ 'Progress against the configured target value.',
+ );
+ ChartBtns.progressBarTargetValueInput().clear().type('50');
+ ChartBtns.progressBarInvertCheckbox()
+ .check({ force: true })
+ .should('be.checked');
+
+ ChartBtns.progressBarWidget().should('be.visible');
+ ChartBtns.progressBarTitle().should('contain.text', 'Job Progress');
+ ChartBtns.progressBarDescription().should(
+ 'contain.text',
+ 'Progress against the configured target value.',
+ );
+ ChartBtns.progressBarStatus().should('contain.text', 'Remaining');
+ ChartBtns.progressBarPercent().should('contain.text', '%');
+ ChartBtns.progressBarPrimaryLabel().should('contain.text', '%');
+ ChartBtns.progressBarSecondaryLabel().should('contain.text', '/');
+ ChartBtns.progressBarFill()
+ .invoke('attr', 'style')
+ .should('match', /width:\s*[0-9.]+%/);
+ });
+});
diff --git a/ui/cypress/tests/chart/chart-types/table.spec.ts
b/ui/cypress/tests/chart/chart-types/table.spec.ts
index 2b775f0793..0b543a7e7b 100644
--- a/ui/cypress/tests/chart/chart-types/table.spec.ts
+++ b/ui/cypress/tests/chart/chart-types/table.spec.ts
@@ -17,6 +17,7 @@
*/
import { ChartUtils } from '../../../support/utils/chart/ChartUtils';
+import { ChartBtns } from '../../../support/utils/chart/ChartBtns';
import { ChartWidgetTableUtils } from
'../../../support/utils/chart/ChartWidgetTableUtils';
import { ChartWidget } from '../../../support/model/ChartWidget';
import { PrepareTestDataUtils } from
'../../../support/utils/PrepareTestDataUtils';
@@ -35,4 +36,21 @@ describe('Test Table View in Charts', () => {
// Check if table is displayed correctly
ChartWidgetTableUtils.checkAmountOfRows(10);
});
+
+ it('Renames table field labels', () => {
+ ChartUtils.addDataViewAndWidget(
+ PrepareTestDataUtils.dataName,
+ ChartWidget.TABLE,
+ );
+
+ ChartUtils.selectDataConfig();
+ ChartBtns.resultLabelInput('randomnumber')
+ .clear()
+ .type('Random Number Label');
+
+ ChartWidgetTableUtils.checkHeaderLabel(
+ 'randomnumber',
+ 'Random Number Label',
+ );
+ });
});
diff --git a/ui/cypress/tests/chart/chart-types/table.spec.ts
b/ui/cypress/tests/chart/chart-types/value-card.spec.ts
similarity index 52%
copy from ui/cypress/tests/chart/chart-types/table.spec.ts
copy to ui/cypress/tests/chart/chart-types/value-card.spec.ts
index 2b775f0793..713a184c6a 100644
--- a/ui/cypress/tests/chart/chart-types/table.spec.ts
+++ b/ui/cypress/tests/chart/chart-types/value-card.spec.ts
@@ -17,11 +17,10 @@
*/
import { ChartUtils } from '../../../support/utils/chart/ChartUtils';
-import { ChartWidgetTableUtils } from
'../../../support/utils/chart/ChartWidgetTableUtils';
-import { ChartWidget } from '../../../support/model/ChartWidget';
import { PrepareTestDataUtils } from
'../../../support/utils/PrepareTestDataUtils';
+import { ChartBtns } from '../../../support/utils/chart/ChartBtns';
-describe('Test Table View in Charts', () => {
+describe('Test Value Card View in Charts', () => {
beforeEach('Setup Test', () => {
ChartUtils.initDataLakeTests();
});
@@ -29,10 +28,27 @@ describe('Test Table View in Charts', () => {
it('Perform Test', () => {
ChartUtils.addDataViewAndWidget(
PrepareTestDataUtils.dataName,
- ChartWidget.TABLE,
+ 'value-card',
);
- // Check if table is displayed correctly
- ChartWidgetTableUtils.checkAmountOfRows(10);
+ ChartUtils.openVisualizationConfig();
+ ChartBtns.valueCardShowTimestampCheckbox()
+ .check({ force: true })
+ .should('be.checked');
+ ChartBtns.valueCardTitleInput().type('Current Snapshot');
+ ChartBtns.valueCardDescriptionInput().type(
+ 'First returned values from the data view.',
+ );
+
+ ChartBtns.valueCardWidget().should('be.visible');
+ ChartBtns.valueCardTitle().should('contain.text', 'Current Snapshot');
+ ChartBtns.valueCardDescription().should(
+ 'contain.text',
+ 'First returned values from the data view.',
+ );
+ ChartBtns.valueCardTimestamp().should('be.visible');
+ ChartBtns.valueCardItems().should('have.length.greaterThan', 0);
+ ChartBtns.valueCardItemLabels().first().should('not.be.empty');
+ ChartBtns.valueCardItemValues().first().should('not.be.empty');
});
});
diff --git
a/ui/src/app/chart-shared/components/charts/progress-bar/config/progress-bar-widget-config.component.html
b/ui/src/app/chart-shared/components/charts/progress-bar/config/progress-bar-widget-config.component.html
index 07eef853c4..c92351b128 100644
---
a/ui/src/app/chart-shared/components/charts/progress-bar/config/progress-bar-widget-config.component.html
+++
b/ui/src/app/chart-shared/components/charts/progress-bar/config/progress-bar-widget-config.component.html
@@ -23,19 +23,22 @@
>
<sp-split-section [level]="3" [title]="'Values' | translate">
<sp-form-field [level]="3" [label]="'Current value field' | translate">
- <sp-select-single-property-config
- [availableProperties]="availableNumericFields"
- [selectedProperty]="
- currentlyConfiguredWidget.visualizationConfig
- .currentValueField
- "
- (changeSelectedProperty)="setCurrentValueField($event)"
- >
- </sp-select-single-property-config>
+ <div data-cy="data-explorer-progress-current-field">
+ <sp-select-single-property-config
+ [availableProperties]="availableNumericFields"
+ [selectedProperty]="
+ currentlyConfiguredWidget.visualizationConfig
+ .currentValueField
+ "
+ (changeSelectedProperty)="setCurrentValueField($event)"
+ >
+ </sp-select-single-property-config>
+ </div>
</sp-form-field>
<sp-form-field [level]="3" [label]="'Target source' | translate">
<mat-radio-group
+ data-cy="data-explorer-progress-target-source"
[ngModel]="
currentlyConfiguredWidget.visualizationConfig.targetSource
"
@@ -55,20 +58,23 @@
'field'
) {
<sp-form-field [level]="3" [label]="'Target field' | translate">
- <sp-select-single-property-config
- [availableProperties]="availableNumericFields"
- [selectedProperty]="
- currentlyConfiguredWidget.visualizationConfig
- .targetField
- "
- (changeSelectedProperty)="setTargetField($event)"
- >
- </sp-select-single-property-config>
+ <div data-cy="data-explorer-progress-target-field">
+ <sp-select-single-property-config
+ [availableProperties]="availableNumericFields"
+ [selectedProperty]="
+ currentlyConfiguredWidget.visualizationConfig
+ .targetField
+ "
+ (changeSelectedProperty)="setTargetField($event)"
+ >
+ </sp-select-single-property-config>
+ </div>
</sp-form-field>
} @else {
<sp-form-field [level]="3" [label]="'Target value' | translate">
<mat-form-field fxFlex="100">
<input
+ data-cy="data-explorer-progress-target-value"
matInput
type="number"
[ngModel]="
@@ -85,6 +91,7 @@
<sp-split-section [level]="3" [title]="'Behavior' | translate">
<sp-form-field [level]="3" [label]="'Display mode' | translate">
<mat-radio-group
+ data-cy="data-explorer-progress-display-mode"
[ngModel]="
currentlyConfiguredWidget.visualizationConfig.displayMode
"
@@ -103,6 +110,7 @@
</sp-form-field>
<mat-checkbox
+ data-cy="data-explorer-progress-show-label"
[checked]="currentlyConfiguredWidget.visualizationConfig.showLabel"
(change)="setShowLabel($event.checked)"
>
@@ -110,6 +118,7 @@
</mat-checkbox>
<mat-checkbox
+ data-cy="data-explorer-progress-invert"
[checked]="
currentlyConfiguredWidget.visualizationConfig.invertProgress
"
@@ -119,6 +128,7 @@
</mat-checkbox>
<mat-checkbox
+ data-cy="data-explorer-progress-clamp"
[checked]="
currentlyConfiguredWidget.visualizationConfig.clampProgress
"
@@ -132,6 +142,7 @@
<sp-form-field [level]="3" [label]="'Title' | translate">
<mat-form-field fxFlex="100">
<input
+ data-cy="data-explorer-progress-title-input"
matInput
type="text"
[(ngModel)]="
@@ -145,6 +156,7 @@
<sp-form-field [level]="3" [label]="'Description' | translate">
<mat-form-field fxFlex="100">
<textarea
+ data-cy="data-explorer-progress-description-input"
matInput
rows="3"
[(ngModel)]="
diff --git
a/ui/src/app/chart-shared/components/charts/progress-bar/progress-bar-widget.component.html
b/ui/src/app/chart-shared/components/charts/progress-bar/progress-bar-widget.component.html
index e5dc11771b..ecde77583c 100644
---
a/ui/src/app/chart-shared/components/charts/progress-bar/progress-bar-widget.component.html
+++
b/ui/src/app/chart-shared/components/charts/progress-bar/progress-bar-widget.component.html
@@ -50,13 +50,19 @@
@if (titleText || descriptionText) {
<div class="progress-copy" fxLayout="column">
@if (titleText) {
- <div class="progress-title">
+ <div
+ class="progress-title"
+ data-cy="progress-bar-title"
+ >
{{ titleText }}
</div>
}
@if (descriptionText) {
- <div class="progress-description">
+ <div
+ class="progress-description"
+ data-cy="progress-bar-description"
+ >
{{ descriptionText }}
</div>
}
@@ -68,18 +74,24 @@
fxLayout="row"
fxLayoutAlign="space-between center"
>
- <span class="progress-status">{{
+ <span class="progress-status" data-cy="progress-bar-status">{{
progressView.statusLabel
}}</span>
@if (showLabel) {
- <span class="progress-percent">{{
- progressView.percentLabel
- }}</span>
+ <span
+ class="progress-percent"
+ data-cy="progress-bar-percent"
+ >{{ progressView.percentLabel }}</span
+ >
}
</div>
- <div class="progress-track">
- <div class="progress-fill" [style.width]="progressWidth"></div>
+ <div class="progress-track" data-cy="progress-bar-track">
+ <div
+ class="progress-fill"
+ data-cy="progress-bar-fill"
+ [style.width]="progressWidth"
+ ></div>
</div>
@if (showLabel) {
@@ -90,7 +102,10 @@
dataExplorerWidget.visualizationConfig.displayMode ===
'percent-and-value'
) {
- <div class="progress-primary-label">
+ <div
+ class="progress-primary-label"
+ data-cy="progress-bar-primary-label"
+ >
{{ progressView.percentLabel }}
</div>
}
@@ -101,7 +116,10 @@
dataExplorerWidget.visualizationConfig.displayMode ===
'percent-and-value'
) {
- <div class="progress-secondary-label">
+ <div
+ class="progress-secondary-label"
+ data-cy="progress-bar-secondary-label"
+ >
{{ progressView.valueLabel }}
</div>
}
diff --git
a/ui/src/app/chart-shared/components/charts/table/table-widget.component.html
b/ui/src/app/chart-shared/components/charts/table/table-widget.component.html
index d64f8316c5..15473d5ab6 100644
---
a/ui/src/app/chart-shared/components/charts/table/table-widget.component.html
+++
b/ui/src/app/chart-shared/components/charts/table/table-widget.component.html
@@ -90,7 +90,16 @@
@if (column === 'time') {
{{ 'Time' | translate }}
} @else {
- {{ headerLabel(column) }}
+ <span
+ [attr.data-cy]="
+
'data-explorer-table-header-' +
+ column
+ "
+ >
+ {{
+ headerLabel(column)
+ }}
+ </span>
}
</span>
<mat-icon class="sort-icon">
diff --git
a/ui/src/app/chart-shared/components/charts/value-card/config/value-card-widget-config.component.html
b/ui/src/app/chart-shared/components/charts/value-card/config/value-card-widget-config.component.html
index 6f5acf1961..54f0165138 100644
---
a/ui/src/app/chart-shared/components/charts/value-card/config/value-card-widget-config.component.html
+++
b/ui/src/app/chart-shared/components/charts/value-card/config/value-card-widget-config.component.html
@@ -43,6 +43,7 @@
<sp-split-section [level]="3" [title]="'Content' | translate">
<sp-form-field [level]="3" [label]="'Timestamp' | translate">
<mat-checkbox
+ data-cy="data-explorer-value-card-show-timestamp"
[checked]="
currentlyConfiguredWidget.visualizationConfig.showTimestamp
"
@@ -59,6 +60,7 @@
<sp-form-field [level]="3" [label]="'Title' | translate">
<mat-form-field fxFlex="100">
<input
+ data-cy="data-explorer-value-card-title-input"
matInput
type="text"
[(ngModel)]="
@@ -72,6 +74,7 @@
<sp-form-field [level]="3" [label]="'Description' | translate">
<mat-form-field fxFlex="100">
<textarea
+ data-cy="data-explorer-value-card-description-input"
matInput
rows="3"
[(ngModel)]="
diff --git
a/ui/src/app/chart-shared/components/charts/value-card/value-card-widget.component.html
b/ui/src/app/chart-shared/components/charts/value-card/value-card-widget.component.html
index 943033f6e4..5d269da2aa 100644
---
a/ui/src/app/chart-shared/components/charts/value-card/value-card-widget.component.html
+++
b/ui/src/app/chart-shared/components/charts/value-card/value-card-widget.component.html
@@ -50,13 +50,19 @@
@if (titleText || descriptionText) {
<div class="value-card-copy" fxLayout="column">
@if (titleText) {
- <div class="value-card-title">
+ <div
+ class="value-card-title"
+ data-cy="value-card-title"
+ >
{{ titleText }}
</div>
}
@if (descriptionText) {
- <div class="value-card-description">
+ <div
+ class="value-card-description"
+ data-cy="value-card-description"
+ >
{{ descriptionText }}
</div>
}
@@ -64,7 +70,10 @@
}
@if (showTimestamp) {
- <div class="value-card-timestamp">
+ <div
+ class="value-card-timestamp"
+ data-cy="value-card-timestamp"
+ >
{{ latestTimestampLabel }}
</div>
}
@@ -75,11 +84,20 @@
[style.--value-card-list-columns]="valueListColumns"
>
@for (card of valueCards; track trackCard($index, card)) {
- <section class="value-card-item">
- <div class="value-card-item-label">
+ <section
+ class="value-card-item"
+ data-cy="value-card-item"
+ >
+ <div
+ class="value-card-item-label"
+ data-cy="value-card-item-label"
+ >
{{ card.label }}
</div>
- <div class="value-card-item-value">
+ <div
+ class="value-card-item-value"
+ data-cy="value-card-item-value"
+ >
{{ card.value }}
</div>
</section>
diff --git
a/ui/src/app/chart/components/chart-view/designer-panel/data-settings/result-label-configuration/result-label-configuration.component.html
b/ui/src/app/chart/components/chart-view/designer-panel/data-settings/result-label-configuration/result-label-configuration.component.html
index f4dbb538c0..57866571ee 100644
---
a/ui/src/app/chart/components/chart-view/designer-panel/data-settings/result-label-configuration/result-label-configuration.component.html
+++
b/ui/src/app/chart/components/chart-view/designer-panel/data-settings/result-label-configuration/result-label-configuration.component.html
@@ -36,6 +36,10 @@
>
<input
matInput
+ [attr.data-cy]="
+ 'data-explorer-result-label-input-' +
+ field.fullDbName
+ "
[ngModel]="getLabel(field)"
(ngModelChange)="updateLabel(field, $event)"
[placeholder]="field.fullDbName"