From 94d49e1c53d3d853c0e7ed443007ba32c0cf9e90 Mon Sep 17 00:00:00 2001 From: karanh37 <33024356+karanh37@users.noreply.github.com> Date: Fri, 28 Jul 2023 14:54:38 +0530 Subject: [PATCH] fix: cypress issues (#12620) * fix: cypress issues * fix: cypress tests * fix: tags cypress * miner fix in tag spec --------- Co-authored-by: Shailesh Parmar --- .../ui/cypress/common/serviceUtils.js | 13 +- .../ui/cypress/constants/constants.js | 26 ++-- .../e2e/Features/UpdateDisplayName.spec.js | 9 +- .../ui/cypress/e2e/Pages/Glossary.spec.js | 115 +++++++++++------- .../ui/cypress/e2e/Pages/Tags.spec.js | 48 ++------ .../ui/src/components/Services/Services.tsx | 4 +- 6 files changed, 110 insertions(+), 105 deletions(-) diff --git a/openmetadata-ui/src/main/resources/ui/cypress/common/serviceUtils.js b/openmetadata-ui/src/main/resources/ui/cypress/common/serviceUtils.js index 6765f265045..b613db924e4 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/common/serviceUtils.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/common/serviceUtils.js @@ -20,6 +20,7 @@ export const visitServiceDetailsPage = (service, verifyHeader = true) => { 'getSettingsPage' ); cy.get('[data-testid="appbar-item-settings"]').should('be.visible').click(); + verifyResponseStatusCode('@getSettingsPage', 200); // Services page interceptURL('GET', '/api/v1/services/*', 'getServices'); @@ -29,7 +30,15 @@ export const visitServiceDetailsPage = (service, verifyHeader = true) => { .should('be.visible') .click(); - verifyResponseStatusCode('@getServices', 200); + cy.wait('@getServices').then((interception) => { + const responseBody = interception.response.body; + // check if service name is received on the first page otherwise, click on Next button + const item = responseBody.data.find((item) => item.name === service.name); + if (!item && responseBody.paging.after) { + cy.get('[data-testid="next"]').click(); + verifyResponseStatusCode('@getServices', 200); + } + }); // click on created service cy.get(`[data-testid="service-name-${service.name}"]`) @@ -43,7 +52,7 @@ export const visitServiceDetailsPage = (service, verifyHeader = true) => { .should('be.visible') .invoke('text') .then((text) => { - expect(text).to.equal(service.name); + expect(text).to.equal(service.displayName); }); } diff --git a/openmetadata-ui/src/main/resources/ui/cypress/constants/constants.js b/openmetadata-ui/src/main/resources/ui/cypress/constants/constants.js index 89fee4c0d9d..91aab500587 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/constants/constants.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/constants/constants.js @@ -236,13 +236,13 @@ export const NEW_TAG = { }; export const NEW_GLOSSARY = { - name: 'Business Glossary', - description: 'This is the Business glossary', + name: 'Cypress Glossary', + description: 'This is the Cypress Glossary', reviewer: 'Aaron Johnson', tag: 'PII.None', }; export const NEW_GLOSSARY_1 = { - name: 'Product%Glossary', + name: 'Cypress Product%Glossary', description: 'This is the Product glossary with percentage', reviewer: 'Brandy Miller', tag: 'PII.None', @@ -250,16 +250,16 @@ export const NEW_GLOSSARY_1 = { export const NEW_GLOSSARY_TERMS = { term_1: { - name: 'Purchase', - description: 'This is the Purchase', + name: 'CypressPurchase', + description: 'This is the Cypress Purchase', synonyms: 'buy,collect,acquire', - fullyQualifiedName: 'Business Glossary.Purchase', + fullyQualifiedName: 'Cypress Glossary.CypressPurchase', }, term_2: { - name: 'Sales', - description: 'This is the Sales', + name: 'CypressSales', + description: 'This is the Cypress Sales', synonyms: 'give,disposal,deal', - fullyQualifiedName: 'Business Glossary.Sales', + fullyQualifiedName: 'Cypress Glossary.CypressSales', }, }; export const GLOSSARY_TERM_WITH_DETAILS = { @@ -267,10 +267,10 @@ export const GLOSSARY_TERM_WITH_DETAILS = { description: 'This is the Accounts', tag: 'PersonalData.Personal', synonyms: 'book,ledger,results', - relatedTerms: 'Sales', + relatedTerms: 'CypressSales', reviewer: 'Colin Ho', inheritedReviewer: 'Aaron Johnson', - fullyQualifiedName: 'Business Glossary.Accounts', + fullyQualifiedName: 'Cypress Glossary.Accounts', }; export const NEW_GLOSSARY_1_TERMS = { @@ -278,13 +278,13 @@ export const NEW_GLOSSARY_1_TERMS = { name: 'Features%Term', description: 'This is the Features', synonyms: 'data,collect,time', - fullyQualifiedName: 'Product%Glossary.Features%Term', + fullyQualifiedName: 'Cypress Product%Glossary.Features%Term', }, term_2: { name: 'Uses', description: 'This is the Uses', synonyms: 'home,business,adventure', - fullyQualifiedName: 'Product%Glossary.Uses', + fullyQualifiedName: 'Cypress Product%Glossary.Uses', }, }; diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Features/UpdateDisplayName.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Features/UpdateDisplayName.spec.js index dc9a36a85f5..6795a68a8e3 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Features/UpdateDisplayName.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Features/UpdateDisplayName.spec.js @@ -63,7 +63,7 @@ describe('Edit displayName for all the entities, services and verify breadcrumb' Object.entries(SERVICES).map(([serviceType, service]) => { it(`${service.type}`, () => { - visitServiceDetailsPage(service); + visitServiceDetailsPage(service, false); updateDisplayName( service.displayName, `/api/v1/services/${serviceType}/*` @@ -85,7 +85,7 @@ describe('Edit displayName for all the entities, services and verify breadcrumb' visitServiceDetailsPage( { type: DASHBOARD_DATA_MODEL.service.type, - name: DASHBOARD_DATA_MODEL.service.displayName, + name: DASHBOARD_DATA_MODEL.service.name, }, false ); @@ -111,6 +111,7 @@ describe('Edit displayName for all the entities, services and verify breadcrumb' SCHEMA_AND_DATABASE_DISPLAY_NAME.serviceName, SCHEMA_AND_DATABASE_DISPLAY_NAME.entity ); + cy.log(SCHEMA_AND_DATABASE_DISPLAY_NAME.database); cy.get('[data-testid="breadcrumb"]') .contains(SCHEMA_AND_DATABASE_DISPLAY_NAME.database) .click(); @@ -223,7 +224,7 @@ describe('Cleanup', () => { visitServiceDetailsPage( { type: DASHBOARD_DATA_MODEL.service.type, - name: DASHBOARD_DATA_MODEL.service.displayName, + name: DASHBOARD_DATA_MODEL.service.name, }, false ); @@ -244,7 +245,7 @@ describe('Cleanup', () => { visitServiceDetailsPage( { type: service.type, - name: service.displayName, + name: service.name, }, false ); diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Glossary.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Glossary.spec.js index 94472ba5f9f..7dc282d4a62 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Glossary.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Glossary.spec.js @@ -61,6 +61,36 @@ const visitGlossaryTermPage = (termName, fqn, fetchPermission) => { cy.get('.ant-tabs .glossary-overview-tab').should('be.visible').click(); }; +const deleteGlossary = (glossary) => { + cy.get('.ant-menu-item').contains(glossary).click(); + cy.get('[data-testid="manage-button"]').should('be.visible').click(); + cy.get('[data-testid="delete-button"]') + .scrollIntoView() + .should('be.visible') + .click(); + + cy.get('[data-testid="delete-confirmation-modal"]') + .should('exist') + .then(() => { + cy.get('[role="dialog"]').should('be.visible'); + cy.get('[data-testid="modal-header"]').should('be.visible'); + }); + cy.get('[data-testid="modal-header"]') + .should('be.visible') + .should('contain', `Delete ${glossary}`); + cy.get('[data-testid="confirmation-text-input"]') + .should('be.visible') + .type(DELETE_TERM); + interceptURL('DELETE', '/api/v1/glossaries/*', 'getGlossary'); + cy.get('[data-testid="confirm-button"]') + .should('be.visible') + .should('not.disabled') + .click(); + verifyResponseStatusCode('@getGlossary', 200); + + toastNotification('Glossary deleted successfully!'); +}; + const checkDisplayName = (displayName) => { cy.get('[data-testid="entity-header-display-name"]') .scrollIntoView() @@ -207,7 +237,7 @@ const goToAssetsTab = (name, fqn, fetchPermission) => { const selectActiveGlossary = (glossaryName) => { interceptURL('GET', '/api/v1/glossaryTerms*', 'getGlossaryTerms'); - cy.get('.ant-menu-item').contains(glossaryName).should('be.visible').click(); + cy.get('.ant-menu-item').contains(glossaryName).click(); verifyResponseStatusCode('@getGlossaryTerms', 200); }; @@ -283,7 +313,10 @@ const updateTerms = (newTerm) => { .scrollIntoView() .should('be.visible') .click({ force: true }); - cy.get('.ant-select-selection-overflow').should('be.visible').click(); + cy.get('.ant-select-selection-overflow') + .should('be.visible') + .click() + .type(newTerm); verifyResponseStatusCode('@getGlossaryTerm', 200); cy.get('.ant-select-item-option-content') .contains(newTerm) @@ -538,14 +571,12 @@ describe('Glossary page should work properly', () => { }); // Verify Product glossary details - cy.get('.ant-menu-item') - .contains(NEW_GLOSSARY_1.name) - .should('be.visible') - .click(); + cy.get('.ant-menu-item').contains(NEW_GLOSSARY_1.name).click(); cy.get('[data-testid="glossary-left-panel"]') .contains(NEW_GLOSSARY_1.name) - .should('be.visible'); + .should('be.visible') + .scrollIntoView(); selectActiveGlossary(NEW_GLOSSARY_1.name); @@ -593,10 +624,7 @@ describe('Glossary page should work properly', () => { interceptURL('GET', `/api/v1/glossaryTerms?glossary=*`, 'glossaryTerm'); interceptURL('GET', `/api/v1/permissions/glossary/*`, 'permissions'); - cy.get('.ant-menu-item') - .contains(NEW_GLOSSARY_1.name) - .should('be.visible') - .click(); + cy.get('.ant-menu-item').contains(NEW_GLOSSARY_1.name).click(); verifyMultipleResponseStatusCode(['@glossaryTerm', '@permissions'], 200); // visit glossary term page @@ -650,10 +678,7 @@ describe('Glossary page should work properly', () => { const entity = SEARCH_ENTITY_TABLE.table_3; - cy.get('.ant-menu-item') - .contains(NEW_GLOSSARY_1.name) - .should('be.visible') - .click(); + cy.get('.ant-menu-item').contains(NEW_GLOSSARY_1.name).click(); goToAssetsTab( NEW_GLOSSARY_1_TERMS.term_1.name, @@ -665,10 +690,29 @@ describe('Glossary page should work properly', () => { ); visitEntityDetailsPage(entity.term, entity.serviceName, entity.entity); + const parentPath = + '[data-testid="entity-right-panel"] [data-testid="glossary-container"]'; + // Add glossary tag to entity for mutually exclusive - cy.get( - '[data-testid="entity-right-panel"] [data-testid="glossary-container"] > [data-testid="entity-tags"] [data-testid="add-tag"]' - ).click(); + cy.get(parentPath).then((glossaryContainer) => { + // Check if the "Add Tag" button is visible + if (!glossaryContainer.find('[data-testid="add-tag"]').is(':visible')) { + // If "Add Tag" is not visible, click on "Edit Tag" + cy.get( + '[data-testid="entity-right-panel"] [data-testid="glossary-container"] [data-testid="edit-button"]' + ).click(); + cy.get('[data-testid="remove-tags"]') + .should('be.visible') + .click({ multiple: true }); + + interceptURL('PATCH', '/api/v1/tables/*', 'removeTags'); + cy.get('[data-testid="saveAssociatedTag"]').scrollIntoView().click(); + verifyResponseStatusCode('@removeTags', 200); + } + }); + + cy.get(`${parentPath} [data-testid="add-tag"]`).click(); + // Select 1st term cy.get('[data-testid="tag-selector"]').click().type(term1); cy.get(`[data-testid="tag-${glossary}.${term1}"]`).click(); @@ -683,6 +727,7 @@ describe('Glossary page should work properly', () => { interceptURL('PATCH', '/api/v1/tables/*', 'saveTag'); cy.get('[data-testid="saveAssociatedTag"]').scrollIntoView(); + cy.clickOutside(); cy.get('[data-testid="saveAssociatedTag"]').click(); verifyResponseStatusCode('@saveTag', 400); toastNotification( @@ -702,6 +747,7 @@ describe('Glossary page should work properly', () => { // Select 2nd term cy.get('[data-testid="tag-selector"]').click().type(term4); cy.get(`[data-testid="tag-${glossary1}.${term4}"]`).click(); + cy.clickOutside(); cy.get('[data-testid="saveAssociatedTag"]').scrollIntoView().click(); verifyResponseStatusCode('@saveTag', 200); verifyResponseStatusCode('@countTag', 200); @@ -726,6 +772,7 @@ describe('Glossary page should work properly', () => { cy.get('[data-testid="tag-selector"] > .ant-select-selector').contains( term3 ); + cy.clickOutside(); cy.get('[data-testid="saveAssociatedTag"]').scrollIntoView().click(); verifyResponseStatusCode('@countTag', 200); cy.get( @@ -778,6 +825,7 @@ describe('Glossary page should work properly', () => { .click({ multiple: true }); interceptURL('PATCH', '/api/v1/tables/*', 'removeTags'); + cy.clickOutside(); cy.get('[data-testid="saveAssociatedTag"]').scrollIntoView().click(); verifyResponseStatusCode('@removeTags', 200); @@ -828,36 +876,9 @@ describe('Glossary page should work properly', () => { }); it('Delete glossary should work properly', () => { + verifyResponseStatusCode('@fetchGlossaries', 200); [NEW_GLOSSARY.name, NEW_GLOSSARY_1.name].forEach((glossary) => { - verifyResponseStatusCode('@fetchGlossaries', 200); - cy.get('.ant-menu-item').contains(glossary).should('be.visible').click(); - - cy.get('[data-testid="manage-button"]').should('be.visible').click(); - cy.get('[data-testid="delete-button"]') - .scrollIntoView() - .should('be.visible') - .click(); - - cy.get('[data-testid="delete-confirmation-modal"]') - .should('exist') - .then(() => { - cy.get('[role="dialog"]').should('be.visible'); - cy.get('[data-testid="modal-header"]').should('be.visible'); - }); - cy.get('[data-testid="modal-header"]') - .should('be.visible') - .should('contain', `Delete ${glossary}`); - cy.get('[data-testid="confirmation-text-input"]') - .should('be.visible') - .type(DELETE_TERM); - interceptURL('DELETE', '/api/v1/glossaries/*', 'getGlossary'); - cy.get('[data-testid="confirm-button"]') - .should('be.visible') - .should('not.disabled') - .click(); - verifyResponseStatusCode('@getGlossary', 200); - - toastNotification('Glossary deleted successfully!'); + deleteGlossary(glossary); }); }); }); diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Tags.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Tags.spec.js index eb3746c42cd..be42c8d0738 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Tags.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Tags.spec.js @@ -381,12 +381,21 @@ describe('Tags page should work', () => { .contains(NEW_CLASSIFICATION.displayName) .should('be.visible') .as('newCategory'); + cy.get('@newCategory') .click() .parent() .should('have.class', 'activeCategory'); verifyResponseStatusCode('@permissions', 200); + cy.get('[data-testid="entity-header-display-name"]') + .invoke('text') + .then((text) => { + // Get the text of the first menu item + if (text !== NEW_CLASSIFICATION.displayName) { + verifyResponseStatusCode('@getTags', 200); + } + }); cy.get('[data-testid="usage-count"]').should('be.visible').as('count'); cy.get('@count') @@ -404,39 +413,6 @@ describe('Tags page should work', () => { verifyResponseStatusCode('@getEntityDetailsPage', 200); }); - it('Rename tag flow should work properly', () => { - cy.get('[data-testid="data-summary-container"]') - .contains(NEW_CLASSIFICATION.displayName) - .should('be.visible') - .as('newCategory'); - - cy.get('@newCategory') - .click() - .parent() - .should('have.class', 'activeCategory'); - cy.get('[data-testid="edit-button"]').should('be.visible').click(); - cy.get('[data-testid="modal-container"]') - .should('exist') - .then(() => { - cy.get('[role="dialog"]').should('be.visible'); - }); - cy.get('[data-testid="header"] > strong') - .should('be.visible') - .contains('Edit Tag'); - - interceptURL('PATCH', '/api/v1/tags/*', 'renamedName'); - cy.get('[data-testid="name"]') - .should('be.visible') - .clear() - .type(NEW_TAG.renamedName); - - submitForm(); - - verifyResponseStatusCode('@renamedName', 200); - - cy.get('[data-testid="table"]').should('contain', NEW_TAG.renamedName); - }); - it('Delete Tag flow should work properly', () => { interceptURL( 'DELETE', @@ -457,7 +433,7 @@ describe('Tags page should work', () => { cy.get('[data-testid="table"]') .should('be.visible') - .should('contain', NEW_TAG.renamedName); + .should('contain', NEW_TAG.name); cy.get('[data-testid="table"]') .find('[data-testid="delete-tag"]') @@ -466,12 +442,12 @@ describe('Tags page should work', () => { .click(); cy.wait(5000); // adding manual wait to open modal, as it depends on click not an api. - permanentDeleteModal(NEW_TAG.renamedName); + permanentDeleteModal(NEW_TAG.name); verifyResponseStatusCode('@deleteTag', 200); cy.wait(5000); // adding manual wait to open modal, as it depends on click not an api. cy.get('[data-testid="table"]') - .contains(NEW_TAG.renamedName) + .contains(NEW_TAG.name) .should('not.be.exist'); }); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Services/Services.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Services/Services.tsx index 0443a31fd64..4e09f2728c1 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Services/Services.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Services/Services.tsx @@ -177,9 +177,7 @@ const Services = ({