From 0ccf03e4d0c244549056d62de48202558a6061a6 Mon Sep 17 00:00:00 2001 From: agorthi Date: Fri, 6 Dec 2024 12:38:52 +0530 Subject: [PATCH 1/5] DI-20595:ACLP Supported regions per service type --- .../dbaas-widgets-verification.spec.ts | 18 +++++++++++++++++- .../linode-widget-verification.spec.ts | 18 +++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/packages/manager/cypress/e2e/core/cloudpulse/dbaas-widgets-verification.spec.ts b/packages/manager/cypress/e2e/core/cloudpulse/dbaas-widgets-verification.spec.ts index 6047d5acec7..38c1654dd79 100644 --- a/packages/manager/cypress/e2e/core/cloudpulse/dbaas-widgets-verification.spec.ts +++ b/packages/manager/cypress/e2e/core/cloudpulse/dbaas-widgets-verification.spec.ts @@ -48,7 +48,23 @@ import { formatToolTip } from 'src/features/CloudPulse/Utils/unitConversion'; const expectedGranularityArray = ['Auto', '1 day', '1 hr', '5 min']; const timeDurationToSelect = 'Last 24 Hours'; -const flags: Partial = { aclp: { enabled: true, beta: true } }; +const flags: Partial = { + aclp: { enabled: true, beta: true }, + aclpResourceTypeMap: [ + { + dimensionKey: 'LINODE_ID', + maxResourceSelections: 10, + serviceType: 'linode', + supportedRegionIds: '', + }, + { + dimensionKey: 'cluster_id', + maxResourceSelections: 10, + serviceType: 'dbaas', + supportedRegionIds: 'us-east, us-ord', + }, + ], +}; const { metrics, diff --git a/packages/manager/cypress/e2e/core/cloudpulse/linode-widget-verification.spec.ts b/packages/manager/cypress/e2e/core/cloudpulse/linode-widget-verification.spec.ts index 12a54f653e2..8b9e289f91f 100644 --- a/packages/manager/cypress/e2e/core/cloudpulse/linode-widget-verification.spec.ts +++ b/packages/manager/cypress/e2e/core/cloudpulse/linode-widget-verification.spec.ts @@ -45,7 +45,23 @@ import { formatToolTip } from 'src/features/CloudPulse/Utils/unitConversion'; */ const expectedGranularityArray = ['Auto', '1 day', '1 hr', '5 min']; const timeDurationToSelect = 'Last 24 Hours'; -const flags: Partial = { aclp: { enabled: true, beta: true } }; +const flags: Partial = { + aclp: { enabled: true, beta: true }, + aclpResourceTypeMap: [ + { + dimensionKey: 'LINODE_ID', + maxResourceSelections: 10, + serviceType: 'linode', + supportedRegionIds: '', + }, + { + dimensionKey: 'cluster_id', + maxResourceSelections: 10, + serviceType: 'dbaas', + supportedRegionIds: '', + }, + ], +}; const { metrics, id, serviceType, dashboardName, region, resource } = widgetDetails.linode; From eaebf7b9357362670bbd740af06886293d4823ed Mon Sep 17 00:00:00 2001 From: agorthi Date: Fri, 6 Dec 2024 14:57:52 +0530 Subject: [PATCH 2/5] DI-20595:ACLP Supported regions per service typ, fixing code review commentse --- .../dbaas-widgets-verification.spec.ts | 22 ++++++++++++++-- .../linode-widget-verification.spec.ts | 25 +++++++++++++++++-- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/packages/manager/cypress/e2e/core/cloudpulse/dbaas-widgets-verification.spec.ts b/packages/manager/cypress/e2e/core/cloudpulse/dbaas-widgets-verification.spec.ts index 38c1654dd79..694359bcaee 100644 --- a/packages/manager/cypress/e2e/core/cloudpulse/dbaas-widgets-verification.spec.ts +++ b/packages/manager/cypress/e2e/core/cloudpulse/dbaas-widgets-verification.spec.ts @@ -61,7 +61,7 @@ const flags: Partial = { dimensionKey: 'cluster_id', maxResourceSelections: 10, serviceType: 'dbaas', - supportedRegionIds: 'us-east, us-ord', + supportedRegionIds: 'us-ord', }, ], }; @@ -111,6 +111,12 @@ const mockRegion = regionFactory.build({ id: 'us-ord', label: 'Chicago, IL', }); + +const extendedMockRegion = regionFactory.build({ + capabilities: ['Managed Databases'], + id: 'us-east', + label: 'Newark,NL', +}); const metricsAPIResponsePayload = cloudPulseMetricsResponseFactory.build({ data: generateRandomMetricsData(timeDurationToSelect, '5 min'), }); @@ -189,7 +195,7 @@ describe('Integration Tests for DBaaS Dashboard ', () => { mockCreateCloudPulseMetrics(serviceType, metricsAPIResponsePayload).as( 'getMetrics' ); - mockGetRegions([mockRegion]); + mockGetRegions([mockRegion, extendedMockRegion]); mockGetUserPreferences({}); mockGetDatabases([databaseMock]).as('getDatabases'); @@ -231,6 +237,18 @@ describe('Integration Tests for DBaaS Dashboard ', () => { // Select a region from the dropdown. ui.regionSelect.find().click(); + + ui.regionSelect.find().type(extendedMockRegion.label); + + // Since DBaaS does not support this region, we expect it to not be in the dropdown. + + ui.autocompletePopper.find().within(() => { + cy.findByText( + `${extendedMockRegion.label} (${extendedMockRegion.id})` + ).should('not.exist'); + }); + + ui.regionSelect.find().click().clear(); ui.regionSelect .findItemByRegionId(mockRegion.id, [mockRegion]) .should('be.visible') diff --git a/packages/manager/cypress/e2e/core/cloudpulse/linode-widget-verification.spec.ts b/packages/manager/cypress/e2e/core/cloudpulse/linode-widget-verification.spec.ts index 8b9e289f91f..a2d968555e5 100644 --- a/packages/manager/cypress/e2e/core/cloudpulse/linode-widget-verification.spec.ts +++ b/packages/manager/cypress/e2e/core/cloudpulse/linode-widget-verification.spec.ts @@ -52,7 +52,7 @@ const flags: Partial = { dimensionKey: 'LINODE_ID', maxResourceSelections: 10, serviceType: 'linode', - supportedRegionIds: '', + supportedRegionIds: 'us-ord', }, { dimensionKey: 'cluster_id', @@ -100,6 +100,12 @@ const mockRegion = regionFactory.build({ id: 'us-ord', label: 'Chicago, IL', }); + +const extendedMockRegion = regionFactory.build({ + capabilities: ['Managed Databases'], + id: 'us-east', + label: 'Newark,NL', +}); const metricsAPIResponsePayload = cloudPulseMetricsResponseFactory.build({ data: generateRandomMetricsData(timeDurationToSelect, '5 min'), }); @@ -195,8 +201,23 @@ describe('Integration Tests for Linode Dashboard ', () => { .should('be.visible') .click(); + ui.regionSelect.find().click(); + + // Select a region from the dropdown. + ui.regionSelect.find().click(); + + ui.regionSelect.find().type(extendedMockRegion.label); + + // Since Linode does not support this region, we expect it to not be in the dropdown. + + ui.autocompletePopper.find().within(() => { + cy.findByText( + `${extendedMockRegion.label} (${extendedMockRegion.id})` + ).should('not.exist'); + }); + // Select a region from the dropdown. - ui.regionSelect.find().click().type(`${region}{enter}`); + ui.regionSelect.find().click().clear().type(`${region}{enter}`); // Select a resource from the autocomplete input. ui.autocomplete From 230661bac00b106f08d071dea0147b5678064ed4 Mon Sep 17 00:00:00 2001 From: agorthi Date: Fri, 6 Dec 2024 19:18:36 +0530 Subject: [PATCH 3/5] adding extra test case for applied-filters and deleteed duplicated validation.spec.ts file --- .../cloudpulse-applied-filters.spec.ts | 277 ++++++++++++++ .../cloudpulse/cloudpulse-validation.spec.ts | 350 ------------------ 2 files changed, 277 insertions(+), 350 deletions(-) create mode 100644 packages/manager/cypress/e2e/core/cloudpulse/cloudpulse-applied-filters.spec.ts delete mode 100644 packages/manager/cypress/e2e/core/cloudpulse/cloudpulse-validation.spec.ts diff --git a/packages/manager/cypress/e2e/core/cloudpulse/cloudpulse-applied-filters.spec.ts b/packages/manager/cypress/e2e/core/cloudpulse/cloudpulse-applied-filters.spec.ts new file mode 100644 index 00000000000..67b27b005ad --- /dev/null +++ b/packages/manager/cypress/e2e/core/cloudpulse/cloudpulse-applied-filters.spec.ts @@ -0,0 +1,277 @@ +/** + * @file Integration Tests for CloudPulse Dbass Dashboard. + */ +import { mockAppendFeatureFlags } from 'support/intercepts/feature-flags'; +import { + mockCreateCloudPulseJWEToken, + mockGetCloudPulseDashboard, + mockCreateCloudPulseMetrics, + mockGetCloudPulseDashboards, + mockGetCloudPulseMetricDefinitions, + mockGetCloudPulseServices, +} from 'support/intercepts/cloudpulse'; +import { ui } from 'support/ui'; +import { widgetDetails } from 'support/constants/widgets'; +import { + accountFactory, + cloudPulseMetricsResponseFactory, + dashboardFactory, + dashboardMetricFactory, + databaseFactory, + regionFactory, + widgetFactory, +} from 'src/factories'; +import { mockGetAccount } from 'support/intercepts/account'; +import { mockGetUserPreferences } from 'support/intercepts/profile'; +import { mockGetRegions } from 'support/intercepts/regions'; +import { Database } from '@linode/api-v4'; +import { generateRandomMetricsData } from 'support/util/cloudpulse'; +import { mockGetDatabases } from 'support/intercepts/databases'; +import type { Flags } from 'src/featureFlags'; + +const timeDurationToSelect = 'Last 24 Hours'; + +const flags: Partial = { aclp: { enabled: true, beta: true } }; + +const { + metrics, + id, + serviceType, + dashboardName, + engine, + clusterName, + nodeType, +} = widgetDetails.dbaas; + +const dashboard = dashboardFactory.build({ + label: dashboardName, + service_type: serviceType, + widgets: metrics.map(({ title, yLabel, name, unit }) => { + return widgetFactory.build({ + label: title, + y_label: yLabel, + metric: name, + unit, + }); + }), +}); + +const metricDefinitions = { + data: metrics.map(({ title, name, unit }) => + dashboardMetricFactory.build({ + label: title, + metric: name, + unit, + }) + ), +}; +const mockAccount = accountFactory.build(); +const mockRegion = regionFactory.build({ + capabilities: ['Managed Databases'], + id: 'us-ord', + label: 'Chicago, IL', +}); +const metricsAPIResponsePayload = cloudPulseMetricsResponseFactory.build({ + data: generateRandomMetricsData(timeDurationToSelect, '5 min'), +}); +const databaseMock: Database = databaseFactory.build({ + label: clusterName, + type: engine, + region: mockRegion.label, + version: '1', + status: 'provisioning', + cluster_size: 1, + engine: 'mysql', + hosts: { + primary: undefined, + secondary: undefined, + }, +}); +const extendDatabaseMock: Database = databaseFactory.build({ + label: 'updated-dbass-mock', + type: engine, + region: mockRegion.label, + version: '1', + status: 'provisioning', + cluster_size: 1, + engine: 'mysql', + hosts: { + primary: undefined, + secondary: undefined, + }, +}); + +describe('Integration Tests for Applied Filters', () => { + beforeEach(() => { + mockAppendFeatureFlags(flags); + mockGetAccount(mockAccount); // Enables the account to have capability for Akamai Cloud Pulse + //mockGetLinodes([mockLinode]); + mockGetCloudPulseMetricDefinitions(serviceType, metricDefinitions); + mockGetCloudPulseDashboards(serviceType, [dashboard]).as('fetchDashboard'); + mockGetCloudPulseServices(serviceType).as('fetchServices'); + mockGetCloudPulseDashboard(id, dashboard); + mockCreateCloudPulseJWEToken(serviceType); + mockCreateCloudPulseMetrics(serviceType, metricsAPIResponsePayload).as( + 'getMetrics' + ); + mockGetRegions([mockRegion]); + mockGetUserPreferences({}); + mockGetDatabases([databaseMock, extendDatabaseMock]); + + // navigate to the cloudpulse page + cy.visitWithLogin('monitor'); + + // Wait for the services and dashboard API calls to complete before proceeding + cy.wait(['@fetchServices', '@fetchDashboard']); + + // Selecting a dashboard from the autocomplete input. + ui.autocomplete + .findByLabel('Dashboard') + .should('be.visible') + .type(dashboardName); + + ui.autocompletePopper + .findByTitle(dashboardName) + .should('be.visible') + .click(); + }); + + it('should verify that the applied global filters are reflected in the filter section', () => { + //Select a Database Engine from the autocomplete input. + ui.autocomplete + .findByLabel('Database Engine') + .should('be.visible') + .type(engine); + + ui.autocompletePopper.findByTitle(engine).should('be.visible').click(); + + // Select a region from the dropdown. + ui.regionSelect.find().click(); + ui.regionSelect + .findItemByRegionId(mockRegion.id, [mockRegion]) + .should('be.visible') + .click(); + + // Select a resource from the autocomplete input. + ui.autocomplete + .findByLabel('Database Clusters') + .should('be.visible') + .type(`${databaseMock.label}{enter}`) + .click(); + cy.findByText(databaseMock.label).should('be.visible'); + + //Select a Node from the autocomplete input. + ui.autocomplete + .findByLabel('Node Type') + .should('be.visible') + .type(`${nodeType}{enter}`); + + // Wait for all metrics query requests to resolve. + cy.wait(['@getMetrics', '@getMetrics', '@getMetrics', '@getMetrics']); + //Collapse the Filters section + ui.button.findByTitle('Filters').should('be.visible').click(); + + cy.get('[data-testid="applied-filter"]').within(() => { + cy.get(`[data-qa-value="Database Engine ${engine}"]`) + cy.get(`[data-qa-value="Region US, Chicago, IL"]`) + cy.get(`[data-qa-value="Node Type ${nodeType}"]`) + cy.get(`[data-qa-value="Database Clusters ${databaseMock.label}"]`) + }); + }); + + it('dont create any global filter and check the applied filters', () => { + //Collapse the Filters section + ui.button.findByTitle('Filters').should('be.visible').click(); + cy.get('[data-testid="applied-filter"]').within(() => { + cy.get('h3').should('not.exist'); + }); + }); + + it('apply only database engine and verify applied filters', () => { + //Select a Database Engine from the autocomplete input. + ui.autocomplete + .findByLabel('Database Engine') + .should('be.visible') + .type(engine); + + ui.autocompletePopper.findByTitle(engine).should('be.visible').click(); + //Collapse the Filters section + ui.button.findByTitle('Filters').should('be.visible').click(); + cy.get('[data-testid="applied-filter"]').within(() => { + cy.get(`[data-qa-value="Database Engine ${engine}"]`) + }); + }); + + it('apply only regions and verify applied filters', () => { + // Select a region from the dropdown. + ui.regionSelect.find().click(); + ui.regionSelect + .findItemByRegionId(mockRegion.id, [mockRegion]) + .should('be.visible') + .click(); + + //Collapse the Filters section + ui.button.findByTitle('Filters').should('be.visible').click(); + cy.get('[data-testid="applied-filter"]').within(() => { + cy.get(`[data-qa-value="Region US, Chicago, IL"]`) + }); + }); + + it('apply only node type and verify applied filters', () => { + //Select a Node from the autocomplete input. + ui.autocomplete + .findByLabel('Node Type') + .should('be.visible') + .type(`${nodeType}{enter}`); + + //Collapse the Filters section + ui.button.findByTitle('Filters').should('be.visible').click(); + cy.get('[data-testid="applied-filter"]').within(() => { + cy.get(`[data-qa-value="Node Type ${nodeType}"]`) + }); + }); + it('should update and verify that the applied global filters are reflected in the filter section', () => { + // Select a region from the dropdown. + ui.regionSelect.find().click(); + ui.regionSelect + .findItemByRegionId(mockRegion.id, [mockRegion]) + .should('be.visible') + .click(); + + //Select a Database Engine from the autocomplete input. + ui.autocomplete + .findByLabel('Database Engine') + .should('be.visible') + .type('PostgreSQL'); + + ui.autocompletePopper + .findByTitle('PostgreSQL') + .should('be.visible') + .click(); + + // Select a resource from the autocomplete input. + ui.autocomplete + .findByLabel('Database Clusters') + .should('be.visible') + .type(`${'Select All'}{enter}`) + .click(); + + //Select a Node from the autocomplete input. + ui.autocomplete + .findByLabel('Node Type') + .should('be.visible') + .type(`${'Primary'}{enter}`); + + // Wait for all metrics query requests to resolve. + cy.wait(['@getMetrics', '@getMetrics', '@getMetrics', '@getMetrics']); + //Collapse the Filters section + ui.button.findByTitle('Filters').should('be.visible').click(); + cy.get('[data-testid="applied-filter"]').within(() => { + cy.get(`[data-qa-value="Database Engine PostgreSQL"]`) + cy.get(`[data-qa-value="Region US, Chicago, IL"]`) + cy.get(`[data-qa-value="Node Type Primary"]`) + cy.get(`[data-qa-value="Database Clusters ${databaseMock.label}"]`) + cy.get(`[data-qa-value="Database Clusters ${extendDatabaseMock.label}"]`) + }); + }); +}); diff --git a/packages/manager/cypress/e2e/core/cloudpulse/cloudpulse-validation.spec.ts b/packages/manager/cypress/e2e/core/cloudpulse/cloudpulse-validation.spec.ts deleted file mode 100644 index 8d92be44b5e..00000000000 --- a/packages/manager/cypress/e2e/core/cloudpulse/cloudpulse-validation.spec.ts +++ /dev/null @@ -1,350 +0,0 @@ -/** - * @file Error Handling Tests for CloudPulse DBaaS Dashboard. - */ -import { mockAppendFeatureFlags } from 'support/intercepts/feature-flags'; -import { - mockCreateCloudPulseJWEToken, - mockGetCloudPulseDashboard, - mockGetCloudPulseDashboards, - mockGetCloudPulseMetricDefinitions, - mockGetCloudPulseServices, -} from 'support/intercepts/cloudpulse'; -import { ui } from 'support/ui'; -import { widgetDetails } from 'support/constants/widgets'; -import { - dashboardFactory, - dashboardMetricFactory, - databaseFactory, - regionFactory, - widgetFactory, -} from 'src/factories'; -import { mockGetUserPreferences } from 'support/intercepts/profile'; -import { mockGetRegions } from 'support/intercepts/regions'; -import { extendRegion } from 'support/util/regions'; -import { mockGetDatabases } from 'support/intercepts/databases'; -import { apiMatcher } from 'support/util/intercepts'; -import { Database } from '@linode/api-v4'; - -/** - * Verifies the presence and values of specific properties within the aclpPreference object - * of the request payload. This function checks that the expected properties exist - * and have the expected values, allowing for validation of user preferences in the application. - * - * @param requestPayload - The payload received from the request, containing the aclpPreference object. - * @param expectedValues - An object containing the expected values for properties to validate against the requestPayload. - */ -const { - metrics, - id, - serviceType, - dashboardName, - region, - engine, - clusterName, - nodeType, -} = widgetDetails.dbaas; - -const dashboard = dashboardFactory.build({ - label: dashboardName, - service_type: serviceType, - widgets: metrics.map(({ title, yLabel, name, unit }) => { - return widgetFactory.build({ - label: title, - y_label: yLabel, - metric: name, - unit, - }); - }), -}); - -const metricDefinitions = { - data: metrics.map(({ title, name, unit }) => - dashboardMetricFactory.build({ - label: title, - metric: name, - unit, - }) - ), -}; - -const mockRegion = extendRegion( - regionFactory.build({ - capabilities: ['Linodes'], - id: 'us-ord', - label: 'Chicago, IL', - country: 'us', - }) -); -const databaseMock: Database = databaseFactory.build({ - label: widgetDetails.dbaas.clusterName, - type: widgetDetails.dbaas.engine, - region: widgetDetails.dbaas.region, - version: '1', - status: 'provisioning', - cluster_size: 1, - engine: 'mysql', -}); - -describe('Tests for API error handling', () => { - beforeEach(() => { - mockAppendFeatureFlags({ - aclp: { beta: true, enabled: true }, - }); - mockGetCloudPulseMetricDefinitions(serviceType, metricDefinitions); - mockGetCloudPulseDashboards(serviceType, [dashboard]).as('fetchDashboard'); - mockGetCloudPulseServices(serviceType).as('fetchServices'); - mockCreateCloudPulseJWEToken(serviceType); - mockGetCloudPulseDashboard(id, dashboard); - mockGetRegions([mockRegion]); - mockGetUserPreferences({}); - mockGetDatabases([databaseMock]).as('getDatabases'); - }); - - it('should return error response when fetching metric definitions API request', () => { - cy.intercept( - 'GET', - apiMatcher(`/monitor/services/${serviceType}/metric-definitions`), - { statusCode: 500, body: { errors: [{ reason: 'Bad Request' }] }, } - ).as('getMetricDefinitions'); - - cy.visitWithLogin('monitor'); - - // Wait for the services and dashboard API calls to complete before proceeding. - cy.wait(['@fetchServices', '@fetchDashboard']); - - // Selecting a dashboard from the autocomplete input. - ui.autocomplete - .findByLabel('Dashboard') - .should('be.visible') - .type(`${dashboardName}{enter}`) - .should('be.visible'); - - // Select a Database Engine from the autocomplete input. - ui.autocomplete - .findByLabel('Database Engine') - .should('be.visible') - .type(`${engine}{enter}`) - .should('be.visible'); - - // Select a region from the dropdown. - ui.regionSelect.find().click().type(`${region}{enter}`); - - // Select a resource (Database Clusters) from the autocomplete input. - ui.autocomplete - .findByLabel('Database Clusters') - .should('be.visible') - .type(`${clusterName}{enter}`) - .click(); - - // Select a Node from the autocomplete input. - ui.autocomplete - .findByLabel('Node Type') - .should('be.visible') - .type(`${nodeType}{enter}`); - - // Wait for the metric definitions API call to resolve. - cy.wait('@getMetricDefinitions'); - cy.get('[data-qa-error-msg="true"]') - .should('be.visible') - .and('have.text', 'Error loading the definitions of metrics.'); - }); - - it('should return error response when fetching services API request', () => { - cy.intercept('GET', apiMatcher(`/monitor/services`), { - statusCode: 500, - body: { - errors: [{ reason: 'Bad Request' }],}, - }).as('fetchServices'); - cy.visitWithLogin('monitor'); - - cy.get('[data-qa-textfield-error-text="Dashboard"]') - .should('be.visible') - .invoke('text') - .then((text) => { - expect(text).to.equal('Failed to fetch the services.'); - }); - }); - it('should return error response when fetching token API request', () => { - cy.intercept('POST', apiMatcher(`/monitor/services/${serviceType}/token`), { - statusCode: 500, - body: { - errors: [{ reason: 'Bad Request' }], }, - }); - - cy.visitWithLogin('monitor'); - // Wait for both the fetch services and fetch dashboard API calls to complete. - cy.wait(['@fetchServices', '@fetchDashboard']); - - // Selecting a dashboard from the autocomplete input. - ui.autocomplete - .findByLabel('Dashboard') - .should('be.visible') - .type(`${dashboardName}{enter}`) - .should('be.visible'); - - // Select a Database Engine from the autocomplete input. - ui.autocomplete - .findByLabel('Database Engine') - .should('be.visible') - .type(`${engine}{enter}`) - .should('be.visible'); - - // Select a region from the dropdown. - ui.regionSelect.find().click().type(`${region}{enter}`); - - // Select a resource (Database Clusters) from the autocomplete input. - ui.autocomplete - .findByLabel('Database Clusters') - .should('be.visible') - .type(`${clusterName}{enter}`) - .click(); - - // Select a Node from the autocomplete input. - ui.autocomplete - .findByLabel('Node Type') - .should('be.visible') - .type(`${nodeType}{enter}`); - - cy.get('[data-qa-error-msg="true"]') - .should('be.visible') - .and('have.text', 'Failed to get the authentication token.'); - }); - - it('should return error response when fetching Dashboards API Request', () => { - mockGetCloudPulseServices(serviceType).as('fetchServices'); - cy.intercept( - 'GET', - apiMatcher(`/monitor/services/${serviceType}/dashboards`), - { - statusCode: 500, - body: { errors: [{ reason: 'Bad Request' }],}, - } - ).as('fetchDashboard'); - - cy.visitWithLogin('monitor'); - // Wait for both the fetch services and fetch dashboard API calls to complete. - cy.wait(['@fetchServices', '@fetchDashboard']); - - // Assert that the error message for fetching the dashboards is displayed correctly. - cy.get('[data-qa-textfield-error-text="Dashboard"]') - .should('be.visible') - .invoke('text') - .then((text) => { - expect(text).to.equal('Failed to fetch the dashboards.'); - }); - }); - - it('should return error message when the Dashboard details API request fails', () => { - cy.intercept('GET', apiMatcher(`/monitor/dashboards/${id}`), { - statusCode: 500, - body: { errors: [{ reason: 'Bad Request' }] }, - }); - - cy.visitWithLogin('monitor'); - - // Select a dashboard from the autocomplete input. Verify that the input is visible before typing. - ui.autocomplete - .findByLabel('Dashboard') - .should('be.visible') - .type(`${dashboardName}{enter}`) - .should('be.visible'); - - // Select a database engine from the autocomplete input. Verify visibility before interaction. - ui.autocomplete - .findByLabel('Database Engine') - .should('be.visible') - .type(`${engine}{enter}`) - .should('be.visible'); - - // Select a region from the dropdown. Verify visibility before interaction. - ui.regionSelect.find().click().type(`${region}{enter}`); - - // Select a database cluster from the autocomplete input. Verify visibility before interaction. - ui.autocomplete - .findByLabel('Database Clusters') - .should('be.visible') - .type(`${clusterName}{enter}`) - .click(); - - // Select a node type from the autocomplete input. Verify visibility before interaction. - ui.autocomplete - .findByLabel('Node Type') - .should('be.visible') - .type(`${nodeType}{enter}`); - - // Wait for the API calls to fetch services and dashboard to resolve. - cy.wait(['@fetchServices', '@fetchDashboard']); - - cy.get('[data-qa-error-msg="true"]') - .should('be.visible') - .and('have.text', 'Failed to fetch the dashboard details.'); - }); - - it(`should return error message when the Regions API request fails`, () => { - cy.intercept('GET', apiMatcher(`regions*`), { - statusCode: 500, - body: { errors: [{ reason: 'Bad Request' }] }, - }); - - cy.visitWithLogin('monitor'); - - // Wait for the services and dashboard API calls to resolve before proceeding. - cy.wait(['@fetchServices', '@fetchDashboard']); - - // Select a dashboard from the autocomplete input. Verify that the input is visible before typing. - ui.autocomplete - .findByLabel('Dashboard') - .should('be.visible') - .type(`${dashboardName}{enter}`) - .should('be.visible'); - - cy.get('[data-qa-textfield-error-text="Region"]') - .should('be.visible') - .invoke('text') - .then((text) => { - expect(text).to.equal('Failed to fetch Region.'); - }); - }); - - it('should return error response when fetching db cluster API request', () => { - cy.intercept('GET', apiMatcher(`databases/instances*`), { - statusCode: 500, - body: {errors: [{ reason: 'Bad Request' }],}, - }); - - cy.visitWithLogin('monitor'); - - //Wait for the services and dashboard API calls to resolve before proceeding. - cy.wait(['@fetchServices', '@fetchDashboard']); - - // Select a dashboard from the autocomplete input - ui.autocomplete - .findByLabel('Dashboard') - .should('be.visible') - .type(`${dashboardName}{enter}`) - .should('be.visible'); - - // Select a Node Type from the autocomplete input. Verify visibility before typing. - ui.autocomplete - .findByLabel('Node Type') - .should('be.visible') - .type(`${nodeType}{enter}`); - - // Select a region from the dropdown. Click and type the region name. - ui.regionSelect.find().click().type(`${region}{enter}`); - - // Select a Database Engine from the autocomplete input. Verify visibility before typing. - ui.autocomplete - .findByLabel('Database Engine') - .should('be.visible') - .type(`${engine}{enter}`) - .should('be.visible'); - - cy.get('[data-qa-textfield-error-text="Database Clusters"]') - .should('be.visible') - .invoke('text') - .then((text) => { - expect(text).to.equal('Failed to fetch Database Clusters.'); - }); - }); -}); From b33f6a47b495c08c56bd326879ad1f957b0d0f94 Mon Sep 17 00:00:00 2001 From: agorthi Date: Sat, 7 Dec 2024 09:58:38 +0530 Subject: [PATCH 4/5] adding new test cases for region select and contextual view --- .../cloudpulse/cloudpulse-navigation.spec.ts | 9 +- .../cloudpulse-region-support.spec.ts | 368 +++++++++++++++ ...ntextual-dbaas-widget-verification.spec.ts | 428 ++++++++++++++++++ 3 files changed, 803 insertions(+), 2 deletions(-) create mode 100644 packages/manager/cypress/e2e/core/cloudpulse/cloudpulse-region-support.spec.ts create mode 100644 packages/manager/cypress/e2e/core/cloudpulse/contextual-dbaas-widget-verification.spec.ts diff --git a/packages/manager/cypress/e2e/core/cloudpulse/cloudpulse-navigation.spec.ts b/packages/manager/cypress/e2e/core/cloudpulse/cloudpulse-navigation.spec.ts index 3cf4fa4f700..7d3cf3543ba 100644 --- a/packages/manager/cypress/e2e/core/cloudpulse/cloudpulse-navigation.spec.ts +++ b/packages/manager/cypress/e2e/core/cloudpulse/cloudpulse-navigation.spec.ts @@ -1,7 +1,12 @@ /** - * @file Integration tests for CloudPulse navigation. + * @file Error Handling Tests for CloudPulse Region Selection + * + * This file contains tests to verify the proper handling of errors + * when interacting with region selection features in CloudPulse. + * The tests focus on scenarios such as invalid or unsupported regions, + * and ensure the application behaves as expected, providing appropriate + * error messages or fallback behavior when necessary. */ - import { mockAppendFeatureFlags } from 'support/intercepts/feature-flags'; import { mockGetAccount } from 'support/intercepts/account'; import { accountFactory } from 'src/factories'; diff --git a/packages/manager/cypress/e2e/core/cloudpulse/cloudpulse-region-support.spec.ts b/packages/manager/cypress/e2e/core/cloudpulse/cloudpulse-region-support.spec.ts new file mode 100644 index 00000000000..9972787f5d2 --- /dev/null +++ b/packages/manager/cypress/e2e/core/cloudpulse/cloudpulse-region-support.spec.ts @@ -0,0 +1,368 @@ +/** + * @file Error Handling Tests for CloudPulse Region Selection + * + * This file contains tests to verify the proper handling of errors + * when interacting with region selection features in CloudPulse. + * The tests focus on scenarios such as invalid or unsupported regions, + * and ensure the application behaves as expected, providing appropriate + * error messages or fallback behavior when necessary. + */ + +import { mockAppendFeatureFlags } from 'support/intercepts/feature-flags'; +import { + mockGetCloudPulseDashboard, + mockGetCloudPulseDashboards, + mockGetCloudPulseServices, +} from 'support/intercepts/cloudpulse'; +import { ui } from 'support/ui'; +import { widgetDetails } from 'support/constants/widgets'; +import { + accountFactory, + dashboardFactory, + regionFactory, + widgetFactory, +} from 'src/factories'; +import { mockGetAccount } from 'support/intercepts/account'; +import { mockGetUserPreferences } from 'support/intercepts/profile'; +import { mockGetRegions } from 'support/intercepts/regions'; +import type { Flags } from 'src/featureFlags'; + +const { metrics, id, serviceType, dashboardName } = widgetDetails.dbaas; + +const dashboard = dashboardFactory.build({ + label: dashboardName, + service_type: serviceType, + widgets: metrics.map(({ title, yLabel, name, unit }) => { + return widgetFactory.build({ + label: title, + y_label: yLabel, + metric: name, + unit, + }); + }), +}); + +const mockAccount = accountFactory.build(); + +const mockRegion = regionFactory.build({ + capabilities: ['Managed Databases'], + id: 'us-ord', + label: 'Chicago, IL', +}); + +const extendedMockRegion = regionFactory.build({ + capabilities: ['Managed Databases'], + id: 'us-east', + label: 'Newark,NL', +}); + +describe('Integration Tests for DBaaS Dashboard ', () => { + beforeEach(() => { + mockGetAccount(mockAccount); // Enables the account to have capability for Akamai Cloud Pulse + mockGetCloudPulseDashboards(serviceType, [dashboard]).as('fetchDashboard'); + mockGetCloudPulseServices(serviceType).as('fetchServices'); + mockGetCloudPulseDashboard(id, dashboard); + mockGetRegions([mockRegion, extendedMockRegion]).as('fetchRegion'); + mockGetUserPreferences({}); + }); + + it('should only display the Chicago region in the dropdown when supportedRegionIds is set to Chicago (us-ord)', () => { + const flags: Partial = { + aclp: { enabled: true, beta: true }, + aclpResourceTypeMap: [ + { + dimensionKey: 'LINODE_ID', + maxResourceSelections: 10, + serviceType: 'linode', + supportedRegionIds: '', + }, + { + dimensionKey: 'cluster_id', + maxResourceSelections: 10, + serviceType: 'dbaas', + supportedRegionIds: 'us-ord', + }, + ], + }; + mockAppendFeatureFlags(flags).as('getFeatureFlags'); + cy.visitWithLogin('monitor'); + cy.wait('@getFeatureFlags'); + + // Selecting a dashboard from the autocomplete input. + ui.autocomplete + .findByLabel('Dashboard') + .should('be.visible') + .type(dashboardName); + + ui.autocompletePopper + .findByTitle(dashboardName) + .should('be.visible') + .click(); + + // Wait for the services and dashboard ,Region API calls to complete before proceeding + cy.wait(['@fetchServices', '@fetchDashboard', '@fetchRegion']); + + // Select a region from the dropdown. + ui.regionSelect.find().click(); + + ui.regionSelect.find().type(extendedMockRegion.label); + + // Since DBaaS does not support this region, we expect it to not be in the dropdown. + + ui.autocompletePopper.find().within(() => { + cy.findByText( + `${extendedMockRegion.label} (${extendedMockRegion.id})` + ).should('not.exist'); + }); + + ui.regionSelect.find().click().clear(); + ui.regionSelect + .findItemByRegionId(mockRegion.id, [mockRegion]) + .should('be.visible') + .click(); + + // Expand the applied filters section + ui.button.findByTitle('Filters').should('be.visible').click(); + + // Verify that the applied filters + cy.get('[data-qa-applied-filter-id="applied-filter"]').within(() => { + cy.get(`[data-qa-value="Region US, Chicago, IL"]`) + .should('be.visible') + .should('have.text', 'US, Chicago, IL'); + }); + }); + + it('should only display mocking region as Chicago and then supportedRegionIds is set to empty', () => { + const flags: Partial = { + aclp: { enabled: true, beta: true }, + aclpResourceTypeMap: [ + { + dimensionKey: 'LINODE_ID', + maxResourceSelections: 10, + serviceType: 'linode', + supportedRegionIds: '', + }, + { + dimensionKey: 'cluster_id', + maxResourceSelections: 10, + serviceType: 'dbaas', + supportedRegionIds: '', + }, + ], + }; + mockAppendFeatureFlags(flags).as('getFeatureFlags'); + cy.visitWithLogin('monitor'); + cy.wait('@getFeatureFlags'); + + // Selecting a dashboard from the autocomplete input. + ui.autocomplete + .findByLabel('Dashboard') + .should('be.visible') + .type(dashboardName); + + ui.autocompletePopper + .findByTitle(dashboardName) + .should('be.visible') + .click(); + + // Wait for the services and dashboard ,Region API calls to complete before proceeding + cy.wait(['@fetchServices', '@fetchDashboard', '@fetchRegion']); + + ui.regionSelect.find().click(); + ui.autocompletePopper.find().within(() => { + cy.get('[data-option-index]').should('have.length', 2); + }); + + ui.regionSelect + .findItemByRegionId(mockRegion.id, [mockRegion]) + .should('be.visible') + .click(); + + // Expand the applied filters section + ui.button.findByTitle('Filters').should('be.visible').click(); + + // Verify that the applied filters + cy.get('[data-qa-applied-filter-id="applied-filter"]').within(() => { + cy.get(`[data-qa-value="Region US, Chicago, IL"]`) + .should('be.visible') + .should('have.text', 'US, Chicago, IL'); + }); + }); + + it('should only display mocking region as Chicago and then supportedRegionIds is set to Junk', () => { + const flags: Partial = { + aclp: { enabled: true, beta: true }, + aclpResourceTypeMap: [ + { + dimensionKey: 'LINODE_ID', + maxResourceSelections: 10, + serviceType: 'linode', + supportedRegionIds: '', + }, + { + dimensionKey: 'cluster_id', + maxResourceSelections: 10, + serviceType: 'dbaas', + supportedRegionIds: 'junk', + }, + ], + }; + mockAppendFeatureFlags(flags).as('getFeatureFlags'); + cy.visitWithLogin('monitor'); + cy.wait('@getFeatureFlags'); + + // Selecting a dashboard from the autocomplete input. + ui.autocomplete + .findByLabel('Dashboard') + .should('be.visible') + .type(dashboardName); + + ui.autocompletePopper + .findByTitle(dashboardName) + .should('be.visible') + .click(); + + // Wait for the services and dashboard ,Region API calls to complete before proceeding + cy.wait(['@fetchServices', '@fetchDashboard', '@fetchRegion']); + + ui.regionSelect.find().click(); + ui.autocompletePopper.find().within(() => { + cy.get('[data-option-index]').should('have.length', 0); + }); + + // Expand the applied filters section + ui.button.findByTitle('Filters').should('be.visible').click(); + + // Verify that the applied filters + cy.get('[data-qa-applied-filter-id="applied-filter"]').within(() => { + cy.get('h3').should('not.exist'); + }); + }); + + it('should only display mocking region as Chicago and then supportedRegionIds is set to us-east', () => { + //Since we are mocking the region as Chicago but setting supportedRegionIds to Newark, + // no region should be displayed in the dropdown, as the region displayed must match the supported region + + const flags: Partial = { + aclp: { enabled: true, beta: true }, + aclpResourceTypeMap: [ + { + dimensionKey: 'LINODE_ID', + maxResourceSelections: 10, + serviceType: 'linode', + supportedRegionIds: '', + }, + { + dimensionKey: 'cluster_id', + maxResourceSelections: 10, + serviceType: 'dbaas', + supportedRegionIds: 'us-east', + }, + ], + }; + mockAppendFeatureFlags(flags).as('getFeatureFlags'); + mockGetRegions([mockRegion]).as('fetchRegion'); + + cy.visitWithLogin('monitor'); + cy.wait('@getFeatureFlags'); + + // Selecting a dashboard from the autocomplete input. + ui.autocomplete + .findByLabel('Dashboard') + .should('be.visible') + .type(dashboardName); + + ui.autocompletePopper + .findByTitle(dashboardName) + .should('be.visible') + .click(); + + // Wait for the services and dashboard ,Region API calls to complete before proceeding + cy.wait(['@fetchServices', '@fetchDashboard', '@fetchRegion']); + + ui.regionSelect.find().click(); + ui.autocompletePopper.find().within(() => { + cy.get('[data-option-index]').should('have.length', 0); + }); + + // Expand the applied filters section + ui.button.findByTitle('Filters').should('be.visible').click(); + + // Verify that the applied filters + cy.get('[data-qa-applied-filter-id="applied-filter"]').within(() => { + cy.get('h3').should('not.exist'); + }); + }); + + it('should only display the Chicago region in the dropdown when supportedRegionIds is set to Chicago (us-ord) with extra spaces', () => { + // Adding extra space to supportedRegionIds with the value ' us-ord', and the value should be trimmed to remove the extra spaces.', + const flags: Partial = { + aclp: { enabled: true, beta: true }, + aclpResourceTypeMap: [ + { + dimensionKey: 'LINODE_ID', + maxResourceSelections: 10, + serviceType: 'linode', + supportedRegionIds: '', + }, + { + dimensionKey: 'cluster_id', + maxResourceSelections: 10, + serviceType: 'dbaas', + supportedRegionIds: 'in-west, us-ord ', + }, + ], + }; + mockAppendFeatureFlags(flags).as('getFeatureFlags'); + cy.visitWithLogin('monitor'); + cy.wait('@getFeatureFlags'); + + // Selecting a dashboard from the autocomplete input. + ui.autocomplete + .findByLabel('Dashboard') + .should('be.visible') + .type(dashboardName); + + ui.autocompletePopper + .findByTitle(dashboardName) + .should('be.visible') + .click(); + + // Wait for the services and dashboard ,Region API calls to complete before proceeding + cy.wait(['@fetchServices', '@fetchDashboard', '@fetchRegion']); + + // Select a region from the dropdown. + ui.regionSelect.find().click(); + + ui.regionSelect.find().type(extendedMockRegion.label); + + // Since DBaaS does not support this region, we expect it to not be in the dropdown. + + ui.autocompletePopper.find().within(() => { + cy.findByText( + `${extendedMockRegion.label} (${extendedMockRegion.id})` + ).should('not.exist'); + }); + + ui.regionSelect.find().click().clear(); + ui.regionSelect + .findItemByRegionId(mockRegion.id, [mockRegion]) + .should('be.visible') + .click(); + + ui.regionSelect.find().click(); + ui.autocompletePopper.find().within(() => { + cy.get('[data-option-index]').should('have.length', 1); + }); + + // Expand the applied filters section + ui.button.findByTitle('Filters').should('be.visible').click(); + + // Verify that the applied filters + cy.get('[data-qa-applied-filter-id="applied-filter"]').within(() => { + cy.get(`[data-qa-value="Region US, Chicago, IL"]`) + .should('be.visible') + .should('have.text', 'US, Chicago, IL'); + }); + }); +}); diff --git a/packages/manager/cypress/e2e/core/cloudpulse/contextual-dbaas-widget-verification.spec.ts b/packages/manager/cypress/e2e/core/cloudpulse/contextual-dbaas-widget-verification.spec.ts new file mode 100644 index 00000000000..ceed564adf2 --- /dev/null +++ b/packages/manager/cypress/e2e/core/cloudpulse/contextual-dbaas-widget-verification.spec.ts @@ -0,0 +1,428 @@ +/** + * @file Integration Tests for contextualview of Dbass Dashboard. + */ +import { mockAppendFeatureFlags } from 'support/intercepts/feature-flags'; +import { + mockCreateCloudPulseJWEToken, + mockGetCloudPulseDashboard, + mockCreateCloudPulseMetrics, + mockGetCloudPulseMetricDefinitions, +} from 'support/intercepts/cloudpulse'; +import { ui } from 'support/ui'; +import { widgetDetails } from 'support/constants/widgets'; +import { + accountFactory, + cloudPulseMetricsResponseFactory, + dashboardFactory, + dashboardMetricFactory, + databaseFactory, + linodeFactory, + regionFactory, + widgetFactory, +} from 'src/factories'; +import { mockGetAccount } from 'support/intercepts/account'; +import { mockGetRegions } from 'support/intercepts/regions'; +import { CloudPulseMetricsResponse, Database } from '@linode/api-v4'; +import { formatToolTip } from 'src/features/CloudPulse/Utils/unitConversion'; +import { generateRandomMetricsData } from 'support/util/cloudpulse'; +import { + mockGetDatabase, + mockGetDatabaseTypes, + mockGetDatabases, +} from 'support/intercepts/databases'; +import { mockDatabaseNodeTypes } from 'support/constants/databases'; +import { randomIp } from 'support/util/random'; +import { extendRegion } from 'support/util/regions'; +import { Flags } from 'src/featureFlags'; +import { generateGraphData } from 'src/features/CloudPulse/Utils/CloudPulseWidgetUtils'; + +/** + * This test ensures that widget titles are displayed correctly on the dashboard. + * This test suite is dedicated to verifying the functionality and display of widgets on the Cloudpulse dashboard. + * It includes: + * Validating that widgets are correctly loaded and displayed. + * Ensuring that widget titles and data match the expected values. + * Verifying that widget settings, such as granularity and aggregation, are applied correctly. + * Testing widget interactions, including zooming and filtering, to ensure proper behavior. + * Each test ensures that widgets on the dashboard operate correctly and display accurate information. + */ +const expectedGranularityArray = ['1 day', '1 hr', '5 min']; +const timeDurationToSelect = 'Last 24 Hours'; + +const { + metrics, + serviceType, + dashboardName, + region, + engine, + clusterName, + nodeType, +} = widgetDetails.dbaas; + +const dashboard = dashboardFactory.build({ + label: dashboardName, + id: 1, + service_type: serviceType, + widgets: metrics.map(({ title, yLabel, name, unit }) => { + return widgetFactory.build({ + label: title, + y_label: yLabel, + metric: name, + unit, + }); + }), +}); + +const metricDefinitions = { + data: metrics.map(({ title, name, unit }) => + dashboardMetricFactory.build({ + label: title, + metric: name, + unit, + }) + ), +}; + +const mockAccount = accountFactory.build(); + +const metricsAPIResponsePayload = cloudPulseMetricsResponseFactory.build({ + data: generateRandomMetricsData(timeDurationToSelect, '5 min'), +}); + +/** + * Generates graph data from a given CloudPulse metrics response and + * extracts average, last, and maximum metric values from the first + * legend row. The values are rounded to two decimal places for + * better readability. + * + * @param responsePayload - The metrics response object containing + * the necessary data for graph generation. + * @param label - The label for the graph, used for display purposes. + * + * @returns An object containing rounded values for max average, last, + * + */ + +const getWidgetLegendRowValuesFromResponse = ( + responsePayload: CloudPulseMetricsResponse, + label: string, + unit: string +) => { + // Generate graph data using the provided parameters + const graphData = generateGraphData({ + flags: { enabled: true } as Partial, + label: label, + metricsList: responsePayload, + resources: [ + { + id: '1', + label: clusterName, + region: 'us-ord', + }, + ], + serviceType: serviceType, + status: 'success', + unit: unit, + }); + + // Destructure metrics data from the first legend row + const { average, last, max } = graphData.legendRowsData[0].data; + + // Round the metrics values to two decimal places + const roundedAverage = formatToolTip(average, unit); + const roundedLast = formatToolTip(last, unit); + const roundedMax = formatToolTip(max, unit); + // Return the rounded values in an object + return { average: roundedAverage, last: roundedLast, max: roundedMax }; +}; + +const allowedIp = randomIp(); + +const databaseMock: Database = databaseFactory.build({ + label: clusterName, + id: 100, + type: engine, + region: region, + version: '1', + status: 'active', + cluster_size: 1, + engine: 'mysql', + allow_list: [allowedIp], +}); +const mockRegion = extendRegion( + regionFactory.build({ + capabilities: ['Managed Databases'], + id: 'us-ord', + label: 'Chicago, IL', + }) +); + +describe('Integration Tests for DBaaS Dashboard ', () => { + beforeEach(() => { + mockAppendFeatureFlags({ + aclp: { beta: true, enabled: true }, + }); + mockGetAccount(mockAccount); + mockGetCloudPulseMetricDefinitions(serviceType, metricDefinitions); + mockGetCloudPulseDashboard(1, dashboard); + mockCreateCloudPulseJWEToken(serviceType); + mockCreateCloudPulseMetrics(serviceType, metricsAPIResponsePayload).as( + 'getMetrics' + ); + mockGetRegions([mockRegion]); + mockGetDatabase(databaseMock).as('getDatabase'); + mockGetDatabases([databaseMock]).as('getDatabases'); + mockGetDatabaseTypes(mockDatabaseNodeTypes).as('getDatabaseTypes'); + + // navigate to the linodes page + cy.visitWithLogin('/linodes'); + + // navigate to the Databases + cy.get('[data-testid="menu-item-Databases"]') + .should('be.visible') // Check if it is visible + .click(); // Click the link + + // navigate to the Monitor + cy.visitWithLogin( + `/databases/${databaseMock.engine}/${databaseMock.id}/monitor` + ); + + // Select a time duration from the autocomplete input. + ui.autocomplete + .findByLabel('Time Range') + .should('be.visible') + .type(`${timeDurationToSelect}{enter}`) + .should('be.visible'); + + //Select a Node from the autocomplete input. + ui.autocomplete + .findByLabel('Node Type') + .should('be.visible') + .type(`${nodeType}{enter}`); + + // Wait for all metrics query requests to resolve. + cy.wait(['@getMetrics', '@getMetrics', '@getMetrics', '@getMetrics']); + }); + + it('should allow users to select their desired granularity and see the most recent data from the API reflected in the graph', () => { + // validate the widget level granularity selection and its metrics + metrics.forEach((testData) => { + const widgetSelector = `[data-qa-widget="${testData.title}"]`; + cy.get(widgetSelector) + .should('be.visible') + .find('h2') + .should('have.text', `${testData.title} (${testData.unit.trim()})`); + cy.get(widgetSelector) + .should('be.visible') + .within(() => { + // check for all available granularity in popper + ui.autocomplete + .findByLabel('Select an Interval') + .should('be.visible') + .click(); + + // Verify tooltip message for granularity selection + + ui.tooltip + .findByText('Data aggregation interval') + .should('be.visible'); + + expectedGranularityArray.forEach((option) => { + ui.autocompletePopper.findByTitle(option).should('exist'); + }); + + mockCreateCloudPulseMetrics( + serviceType, + metricsAPIResponsePayload + ).as('getGranularityMetrics'); + + //find the interval component and select the expected granularity + ui.autocomplete + .findByLabel('Select an Interval') + .should('be.visible') + .type(`${testData.expectedGranularity}{enter}`); //type expected granularity + + //check if the API call is made correctly with time granularity value selected + cy.wait('@getGranularityMetrics').then((interception) => { + expect(interception) + .to.have.property('response') + .with.property('statusCode', 200); + expect(testData.expectedGranularity).to.include( + interception.request.body.time_granularity.value + ); + }); + + //validate the widget areachart is present + cy.get('.recharts-responsive-container').within(() => { + const expectedWidgetValues = getWidgetLegendRowValuesFromResponse( + metricsAPIResponsePayload, + testData.title, + testData.unit + ); + const graphRowTitle = `[data-qa-graph-row-title="${testData.title} (${testData.unit})"]`; + + cy.get(graphRowTitle) + .should('be.visible') + .should('have.text', `${testData.title} (${testData.unit})`); + + cy.get(`[data-qa-graph-column-title="Max"]`) + .should('be.visible') + .should('have.text', `${expectedWidgetValues.max}`); + + cy.get(`[data-qa-graph-column-title="Avg"]`) + .should('be.visible') + .should('have.text', `${expectedWidgetValues.average}`); + + cy.get(`[data-qa-graph-column-title="Last"]`) + .should('be.visible') + .should('have.text', `${expectedWidgetValues.last}`); + }); + }); + }); + }); + + it('should allow users to select the desired aggregation and view the latest data from the API displayed in the graph', () => { + metrics.forEach((testData) => { + const widgetSelector = `[data-qa-widget="${testData.title}"]`; + cy.get(widgetSelector) + .should('be.visible') + .within(() => { + mockCreateCloudPulseMetrics( + serviceType, + metricsAPIResponsePayload + ).as('getAggregationMetrics'); + + //find the interval component and select the expected granularity + ui.autocomplete + .findByLabel('Select an Aggregate Function') + .should('be.visible') + .type(`${testData.expectedAggregation}{enter}`); //type expected granularity + + // Verify tooltip message for aggregation selection + + ui.tooltip.findByText('Aggregation function').should('be.visible'); + + //check if the API call is made correctly with time granularity value selected + cy.wait('@getAggregationMetrics').then((interception) => { + expect(interception) + .to.have.property('response') + .with.property('statusCode', 200); + expect(testData.expectedAggregation).to.equal( + interception.request.body.aggregate_function + ); + }); + + //validate the widget areachart is present + cy.get('.recharts-responsive-container').within(() => { + const expectedWidgetValues = getWidgetLegendRowValuesFromResponse( + metricsAPIResponsePayload, + testData.title, + testData.unit + ); + const graphRowTitle = `[data-qa-graph-row-title="${testData.title} (${testData.unit})"]`; + cy.get(graphRowTitle) + .should('be.visible') + .should('have.text', `${testData.title} (${testData.unit})`); + + cy.get(`[data-qa-graph-column-title="Max"]`) + .should('be.visible') + .should('have.text', `${expectedWidgetValues.max}`); + + cy.get(`[data-qa-graph-column-title="Avg"]`) + .should('be.visible') + .should('have.text', `${expectedWidgetValues.average}`); + + cy.get(`[data-qa-graph-column-title="Last"]`) + .should('be.visible') + .should('have.text', `${expectedWidgetValues.last}`); + }); + }); + }); + }); + + it('should zoom in and out of all the widgets', () => { + // do zoom in and zoom out test on all the widgets + metrics.forEach((testData) => { + cy.get(`[data-qa-widget="${testData.title}"]`).as('widget'); + cy.get('@widget') + .should('be.visible') + .within(() => { + ui.button + .findByAttribute('aria-label', 'Zoom In') + .should('be.visible') + .should('be.enabled') + .click(); + + // Verify tooltip message for Zoom-in + + ui.tooltip.findByText('Maximize').should('be.visible'); + + cy.get('@widget').should('be.visible'); + + //validate the widget areachart is present + cy.get('.recharts-responsive-container').within(() => { + const expectedWidgetValues = getWidgetLegendRowValuesFromResponse( + metricsAPIResponsePayload, + testData.title, + testData.unit + ); + + const graphRowTitle = `[data-qa-graph-row-title="${testData.title} (${testData.unit})"]`; + cy.get(graphRowTitle) + .should('be.visible') + .should('have.text', `${testData.title} (${testData.unit})`); + + cy.get(`[data-qa-graph-column-title="Max"]`) + .should('be.visible') + .should('have.text', `${expectedWidgetValues.max}`); + + cy.get(`[data-qa-graph-column-title="Avg"]`) + .should('be.visible') + .should('have.text', `${expectedWidgetValues.average}`); + + cy.get(`[data-qa-graph-column-title="Last"]`) + .should('be.visible') + .should('have.text', `${expectedWidgetValues.last}`); + }); + + // click zoom out and validate the same + ui.button + .findByAttribute('aria-label', 'Zoom Out') + .should('be.visible') + .should('be.enabled') + .scrollIntoView() + .click({ force: true }); + + // Verify tooltip message for Zoom-out + + ui.tooltip.findByText('Minimize').should('be.visible'); + + cy.get('@widget').should('be.visible'); + + cy.get('.recharts-responsive-container').within(() => { + const expectedWidgetValues = getWidgetLegendRowValuesFromResponse( + metricsAPIResponsePayload, + testData.title, + testData.unit + ); + const graphRowTitle = `[data-qa-graph-row-title="${testData.title} (${testData.unit})"]`; + cy.get(graphRowTitle) + .should('be.visible') + .should('have.text', `${testData.title} (${testData.unit})`); + + cy.get(`[data-qa-graph-column-title="Max"]`) + .should('be.visible') + .should('have.text', `${expectedWidgetValues.max}`); + + cy.get(`[data-qa-graph-column-title="Avg"]`) + .should('be.visible') + .should('have.text', `${expectedWidgetValues.average}`); + + cy.get(`[data-qa-graph-column-title="Last"]`) + .should('be.visible') + .should('have.text', `${expectedWidgetValues.last}`); + }); + }); + }); + }); +}); From 4de3ea6003f62421056f0af4fe8988367c8e1d8a Mon Sep 17 00:00:00 2001 From: agorthi Date: Mon, 9 Dec 2024 12:25:00 +0530 Subject: [PATCH 5/5] Please only validate the files dbaas-widgets-verification.spec.ts and linode-widget-verification.spec.ts. other files only for aclp-manager regression simulation --- .../e2e/core/cloudpulse/cloudpulse-navigation.spec.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/manager/cypress/e2e/core/cloudpulse/cloudpulse-navigation.spec.ts b/packages/manager/cypress/e2e/core/cloudpulse/cloudpulse-navigation.spec.ts index 7d3cf3543ba..3cf4fa4f700 100644 --- a/packages/manager/cypress/e2e/core/cloudpulse/cloudpulse-navigation.spec.ts +++ b/packages/manager/cypress/e2e/core/cloudpulse/cloudpulse-navigation.spec.ts @@ -1,12 +1,7 @@ /** - * @file Error Handling Tests for CloudPulse Region Selection - * - * This file contains tests to verify the proper handling of errors - * when interacting with region selection features in CloudPulse. - * The tests focus on scenarios such as invalid or unsupported regions, - * and ensure the application behaves as expected, providing appropriate - * error messages or fallback behavior when necessary. + * @file Integration tests for CloudPulse navigation. */ + import { mockAppendFeatureFlags } from 'support/intercepts/feature-flags'; import { mockGetAccount } from 'support/intercepts/account'; import { accountFactory } from 'src/factories';