From 09d3e67fd2ff45a669ad39cd1d19276b92b1e775 Mon Sep 17 00:00:00 2001 From: Nizamudeen A Date: Fri, 27 Sep 2024 10:58:41 +0530 Subject: [PATCH] mgr/dashboard: fixing cephadm dashboard e2e failures the wizard component changes caused issue to the e2e, so fixing it. It was uncaught before because of the test were unable to run due to some lab issues. Fixes: https://tracker.ceph.com/issues/68871 Signed-off-by: Nizamudeen A --- .../frontend/cypress/e2e/cluster/hosts.po.ts | 3 +- .../frontend/cypress/e2e/cluster/osds.po.ts | 3 +- .../create-cluster.feature.po.ts | 4 +-- .../e2e/common/forms-helper.feature.po.ts | 13 +++++---- .../02-create-cluster-add-host.feature | 11 +++---- ...create-cluster-create-services.e2e-spec.ts | 5 +++- .../04-create-cluster-create-osds.e2e-spec.ts | 12 ++++++-- .../05-create-cluster-review.e2e-spec.ts | 8 ++--- .../workflow/06-cluster-check.e2e-spec.ts | 8 +++-- .../app/ceph/cluster/hosts/hosts.component.ts | 2 +- .../dynamic-input-combobox.directive.ts | 29 ++++++++++--------- .../app/shared/services/combo-box.service.ts | 3 +- 12 files changed, 55 insertions(+), 46 deletions(-) diff --git a/src/pybind/mgr/dashboard/frontend/cypress/e2e/cluster/hosts.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/e2e/cluster/hosts.po.ts index 7c2db0efd06..43ef2d5cd50 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/e2e/cluster/hosts.po.ts +++ b/src/pybind/mgr/dashboard/frontend/cypress/e2e/cluster/hosts.po.ts @@ -21,7 +21,7 @@ export class HostsPageHelper extends PageHelper { add(hostname: string, exist?: boolean, maintenance?: boolean, labels: string[] = []) { cy.get(`${this.pages.add.id}`).within(() => { - cy.get('#hostname').type(hostname); + cy.get('#hostname').type(hostname, { force: true }); if (maintenance) { cy.get('label[for=maintenance]').click(); } @@ -35,6 +35,7 @@ export class HostsPageHelper extends PageHelper { } cy.get('cd-submit-button').click(); + cy.get('cds-modal').should('not.exist'); // back to host list cy.get(`${this.pages.index.id}`); } diff --git a/src/pybind/mgr/dashboard/frontend/cypress/e2e/cluster/osds.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/e2e/cluster/osds.po.ts index ad7224de121..b35a94050a1 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/e2e/cluster/osds.po.ts +++ b/src/pybind/mgr/dashboard/frontend/cypress/e2e/cluster/osds.po.ts @@ -50,9 +50,8 @@ export class OSDsPageHelper extends PageHelper { @PageHelper.restrictTo(pages.index.url) checkStatus(id: number, status: string[]) { - this.searchTable(`id:${id}`); + this.searchTable(id.toString()); cy.wait(5 * 1000); - this.expectTableCount('found', 1); cy.get(`[cdstabledata]:nth-child(${this.columnIndex.status}) .badge`).should(($ele) => { const allStatus = $ele.toArray().map((v) => v.innerText); for (const s of status) { diff --git a/src/pybind/mgr/dashboard/frontend/cypress/e2e/common/create-cluster/create-cluster.feature.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/e2e/common/create-cluster/create-cluster.feature.po.ts index d18c3485546..76c3cedf653 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/e2e/common/create-cluster/create-cluster.feature.po.ts +++ b/src/pybind/mgr/dashboard/frontend/cypress/e2e/common/create-cluster/create-cluster.feature.po.ts @@ -2,8 +2,8 @@ import { Given, Then } from 'cypress-cucumber-preprocessor/steps'; Given('I am on the {string} section', (page: string) => { cy.get('cd-wizard').within(() => { - cy.get('.nav-link').should('contain.text', page).first().click(); - cy.get('.nav-link.active').should('contain.text', page); + cy.get('button').should('have.attr', 'title', page).first().click(); + cy.get('.cds--assistive-text').should('contain.text', 'Current'); }); }); diff --git a/src/pybind/mgr/dashboard/frontend/cypress/e2e/common/forms-helper.feature.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/e2e/common/forms-helper.feature.po.ts index a43a304c680..6252fc7e99d 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/e2e/common/forms-helper.feature.po.ts +++ b/src/pybind/mgr/dashboard/frontend/cypress/e2e/common/forms-helper.feature.po.ts @@ -42,16 +42,17 @@ And('select options {string}', (labels: string) => { And('{string} option {string}', (action: string, labels: string) => { if (labels) { + cy.get('cds-modal').find('input[id=labels]').click(); if (action === 'add') { - cy.get('cd-modal').find('.select-menu-edit').click(); for (const label of labels.split(', ')) { - cy.get('.popover-body input').type(`${label}{enter}`); + cy.get('input[id=labels]').clear().type(`${label}`); + + cy.get('cds-dropdown-list').find('li').should('have.attr', 'title', label).click(); } } else { for (const label of labels.split(', ')) { - cy.contains('cd-modal .badge', new RegExp(`^${label}$`)) - .find('.badge-remove') - .click(); + cy.get('input[id=labels]').clear().type(`${label}`); + cy.get('cds-dropdown-list').find('li').should('have.attr', 'title', label).click(); } } } @@ -84,7 +85,7 @@ And('I confirm to {string} on carbon modal', (action: string) => { }); Then('I should see an error in {string} field', (field: string) => { - cy.get('cd-modal').within(() => { + cy.get('cds-modal').within(() => { cy.get(`input[id=${field}]`).should('have.class', 'ng-invalid'); }); }); diff --git a/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/02-create-cluster-add-host.feature b/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/02-create-cluster-add-host.feature index b9578f8c03d..0c62d576aa5 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/02-create-cluster-add-host.feature +++ b/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/02-create-cluster-add-host.feature @@ -12,10 +12,9 @@ Feature: Cluster expansion host addition Scenario Outline: Add hosts Given I am on the "Add Hosts" section When I click on "Add" button - And enter "hostname" "" in the modal - And select options "" + And enter "hostname" "" in the carbon modal + And "add" option "" And I click on "Add Host" button - Then I should not see the modal And I should see a row with "" And I should see row "" have "" @@ -32,7 +31,6 @@ Feature: Cluster expansion host addition Then I should see the carbon modal And I check the tick box in carbon modal And I click on "Remove Host" button - Then I should not see the carbon modal And I should not see a row with "" Examples: @@ -43,9 +41,8 @@ Feature: Cluster expansion host addition Scenario: Add hosts using pattern 'ceph-node-[01-02]' Given I am on the "Add Hosts" section When I click on "Add" button - And enter "hostname" "ceph-node-[01-02]" in the modal + And enter "hostname" "ceph-node-[01-02]" in the carbon modal And I click on "Add Host" button - Then I should not see the modal And I should see rows with following entries | hostname | | ceph-node-01 | @@ -55,7 +52,7 @@ Feature: Cluster expansion host addition Given I am on the "Add Hosts" section And I should see a row with "ceph-node-00" When I click on "Add" button - And enter "hostname" "ceph-node-00" in the modal + And enter "hostname" "ceph-node-00" in the carbon modal Then I should see an error in "hostname" field Scenario Outline: Add and remove labels on host diff --git a/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/03-create-cluster-create-services.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/03-create-cluster-create-services.e2e-spec.ts index 0118c85c113..0f55fd9a99f 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/03-create-cluster-create-services.e2e-spec.ts +++ b/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/03-create-cluster-create-services.e2e-spec.ts @@ -19,7 +19,10 @@ describe('Create cluster create services page', () => { cy.login(); createCluster.navigateTo(); createCluster.createCluster(); - cy.get('.nav-link').contains('Create Services').click(); + + cy.get('cd-wizard').within(() => { + cy.get('button').contains('Create Services').click(); + }); }); it('should check if title contains Create Services', () => { diff --git a/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/04-create-cluster-create-osds.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/04-create-cluster-create-osds.e2e-spec.ts index 5583d37fd12..858126774f8 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/04-create-cluster-create-osds.e2e-spec.ts +++ b/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/04-create-cluster-create-osds.e2e-spec.ts @@ -12,7 +12,9 @@ describe('Create cluster create osds page', () => { cy.login(); createCluster.navigateTo(); createCluster.createCluster(); - cy.get('.nav-link').contains('Create OSDs').click(); + cy.get('cd-wizard').within(() => { + cy.get('button').contains('Create OSDs').click(); + }); }); it('should check if title contains Create OSDs', () => { @@ -28,12 +30,16 @@ describe('Create cluster create osds page', () => { // Go to the Review section and Expand the cluster // because the drive group spec is only stored // in frontend and will be lost when refreshed - cy.get('.nav-link').contains('Review').click(); + cy.get('cd-wizard').within(() => { + cy.get('button').contains('Review').click(); + }); cy.get('button[aria-label="Next"]').click(); cy.get('cd-dashboard').should('exist'); createCluster.navigateTo(); createCluster.createCluster(); - cy.get('.nav-link').contains('Create OSDs').click(); + cy.get('cd-wizard').within(() => { + cy.get('button').contains('Create OSDs').click(); + }); } }); }); diff --git a/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/05-create-cluster-review.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/05-create-cluster-review.e2e-spec.ts index d5b4a368d39..b0acb6964aa 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/05-create-cluster-review.e2e-spec.ts +++ b/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/05-create-cluster-review.e2e-spec.ts @@ -14,12 +14,8 @@ describe('Create Cluster Review page', () => { createCluster.navigateTo(); createCluster.createCluster(); - cy.get('.nav-link').contains('Review').click(); - }); - - describe('navigation link test', () => { - it('should check if active nav-link is of Review section', () => { - cy.get('.nav-link.active').should('contain.text', 'Review'); + cy.get('cd-wizard').within(() => { + cy.get('button').contains('Review').click(); }); }); diff --git a/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/06-cluster-check.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/06-cluster-check.e2e-spec.ts index 722741a6cc5..e1c66c0f4af 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/06-cluster-check.e2e-spec.ts +++ b/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/06-cluster-check.e2e-spec.ts @@ -21,10 +21,14 @@ describe('when cluster creation is completed', () => { // Explicitly skip OSD Creation Step so that it prevents from // deploying OSDs to the hosts automatically. - cy.get('.nav-link').contains('Create OSDs').click(); + cy.get('cd-wizard').within(() => { + cy.get('button').contains('Create OSDs').click(); + }); cy.get('button[aria-label="Skip this step"]').click(); - cy.get('.nav-link').contains('Review').click(); + cy.get('cd-wizard').within(() => { + cy.get('button').contains('Review').click(); + }); cy.get('button[aria-label="Next"]').click(); cy.get('cd-dashboard').should('exist'); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.ts index 7a3bbf079d8..d652465846a 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.ts @@ -328,7 +328,7 @@ export class HostsComponent extends ListWithDetails implements OnDestroy, OnInit const host = this.selection.first(); const labels = new Set(resp.concat(this.hostService.predefinedLabels)); const allLabels = Array.from(labels).map((label) => { - return { content: label }; + return { content: label, selected: host['labels'].includes(label) }; }); this.cdsModalService.show(FormModalComponent, { titleText: $localize`Edit Host: ${host.hostname}`, diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dynamic-input-combobox.directive.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dynamic-input-combobox.directive.ts index 0f7d9941577..2645e466ec6 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dynamic-input-combobox.directive.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dynamic-input-combobox.directive.ts @@ -1,4 +1,12 @@ -import { Directive, Input, OnDestroy, OnInit, Output, EventEmitter, HostListener } from '@angular/core'; +import { + Directive, + Input, + OnDestroy, + OnInit, + Output, + EventEmitter, + HostListener +} from '@angular/core'; import { ComboBoxItem } from '../models/combo-box.model'; import { ComboBoxService } from '../services/combo-box.service'; import { Subject, Subscription } from 'rxjs'; @@ -15,9 +23,6 @@ export const DEBOUNCE_TIMER = 300; selector: '[cdDynamicInputCombobox]' }) export class DynamicInputComboboxDirective implements OnInit, OnDestroy { - /** - * This input is the same as what we have in the element. - */ @Input() items: ComboBoxItem[]; /** @@ -29,9 +34,7 @@ export class DynamicInputComboboxDirective implements OnInit, OnDestroy { private searchSubject: Subject = new Subject(); private selectedItems: ComboBoxItem[] = []; - constructor( - private combBoxService: ComboBoxService - ) { } + constructor(private combBoxService: ComboBoxService) {} ngOnInit() { this.searchSubscription = this.searchSubject @@ -52,12 +55,12 @@ export class DynamicInputComboboxDirective implements OnInit, OnDestroy { const exists = this.items.some( (item: ComboBoxItem) => item.content === searchString ); - - if (!exists) { - this.items = this.items.concat({ content: searchString, name: searchString }); - } - this.updatedItems.emit(this.items ); - this.combBoxService.emit({ searchString }); + + if (!exists) { + this.items = this.items.concat({ content: searchString, name: searchString }); + } + this.updatedItems.emit(this.items); + this.combBoxService.emit({ searchString }); }); } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/combo-box.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/combo-box.service.ts index bb193b18592..6d8208e69a0 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/combo-box.service.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/combo-box.service.ts @@ -7,8 +7,7 @@ import { Subject } from 'rxjs'; export class ComboBoxService { private searchSubject = new Subject<{ searchString: string }>(); - constructor() { - } + constructor() {} emit(value: { searchString: string }) { this.searchSubject.next(value); -- 2.39.5